home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / network / samba / patches / samba-1.024 / samba-1
Encoding:
Text File  |  1995-11-10  |  96.6 KB  |  3,430 lines

  1. diff -u -r --new-file last-version/source/Makefile samba-1.9.14p4/source/Makefile
  2. --- last-version/source/Makefile    Tue Nov  7 22:58:21 1995
  3. +++ samba-1.9.14p4/source/Makefile    Fri Nov 10 18:50:20 1995
  4. @@ -85,10 +85,12 @@
  5.  # DCE_LIBS =
  6.  
  7.  # This is for SMB encrypted (lanman) passwords.
  8. +# you may wish to add -DREPLACE_GETPASS if your getpass() is limited
  9. +# to 8 chars
  10.  # DES_BASE=/usr/local/libdes
  11.  # DES_FLAGS= -I$(DES_BASE)
  12.  # DES_LIB= -L$(DES_BASE) -ldes
  13. -# PASSWD_FLAGS=-DSMB_PASSWD -DSMBGETPASS -DSMB_PASSWD_FILE=\"$(BASEDIR)/private/smbpasswd\"
  14. +# PASSWD_FLAGS=-DSMB_PASSWD -DSMB_PASSWD_FILE=\"$(BASEDIR)/private/smbpasswd\"
  15.  
  16.  ######################################
  17.  # VTP-Support
  18. @@ -353,7 +355,7 @@
  19.  # contributed by cjkiick@flinx.b11.ingr.com
  20.  # modified by ttj@sknsws61.sjo.statkart.no
  21.  # FLAGSM = -DCLIX -D_INGR_EXTENSIONS=1
  22. -# LIBSM = -lbsd
  23. +# LIBSM = -lbsd -lc_s
  24.  
  25.  # This is for DGUX. 
  26.  # Contributed by ross@augie.insci.com (Ross Andrus)
  27. @@ -423,7 +425,7 @@
  28.  LIBS = $(LIBS1) $(LIBSM) $(DCE_LIBS) $(DES_LIB)
  29.  
  30.  PROGS1 = smbd smbclient nmbd testparm testprns smbrun smbstatus smbpasswd 
  31. -PROGS = $(PROGS1) nmbd2
  32. +PROGS = $(PROGS1) nmbd2 nmblookup
  33.  SCRIPTS = smbtar
  34.  
  35.  all : CHECK $(PROGS)
  36. @@ -464,13 +466,17 @@
  37.      @echo Linking nmbd
  38.      @$(CC) $(CFLAGS) -o nmbd nameserv.o $(UTILOBJ) $(LIBS)
  39.  
  40. +nmblookup: nmblookup.o $(UTILOBJ)  
  41. +    @echo Linking nmblookup
  42. +    @$(CC) $(CFLAGS) -o nmblookup nmblookup.o nmblib.o $(UTILOBJ) $(LIBS)
  43. +
  44.  nmbd2: nameserv2.o nmblib.o $(UTILOBJ) 
  45.      @echo Linking nmbd2
  46.      @$(CC) $(CFLAGS) -o nmbd2 nameserv2.o nmblib.o $(UTILOBJ) $(LIBS)
  47.  
  48. -smbclient: client.o clitar.o $(UTILOBJ) 
  49. +smbclient: client.o clitar.o getsmbpass.o $(UTILOBJ) 
  50.      @echo Linking smbclient
  51. -    @$(CC) $(CFLAGS) -o smbclient client.o clitar.o $(UTILOBJ) $(LIBS)
  52. +    @$(CC) $(CFLAGS) -o smbclient client.o clitar.o getsmbpass.o $(UTILOBJ) $(LIBS)
  53.  
  54.  smbstatus: status.o $(PARAMOBJ) 
  55.      @echo Linking smbstatus
  56. @@ -486,7 +492,7 @@
  57.  
  58.  smbpasswd: smbpasswd.o getsmbpass.o $(PARAMOBJ)
  59.      @echo Linking smbpasswd
  60. -    @$(CC) $(CFLAGS) -o smbpasswd getsmbpass.o smbpasswd.o $(PARAMOBJ) $(LIBS)
  61. +    @$(CC) $(CFLAGS) -o smbpasswd smbpasswd.o getsmbpass.o $(PARAMOBJ) $(LIBS)
  62.  
  63.  install: installbin installman
  64.  
  65. diff -u -r --new-file last-version/source/change-log samba-1.9.14p4/source/change-log
  66. --- last-version/source/change-log    Tue Nov  7 22:59:06 1995
  67. +++ samba-1.9.14p4/source/change-log    Fri Nov 10 22:55:26 1995
  68. @@ -1628,7 +1628,16 @@
  69.      - is08859-1 patches from eauth@mail.cso.co.at
  70.      - starting rewriting nmbd, new nmbd is nmbd2, old one still around
  71.      for time being
  72. +    - released p3
  73. +    - rewrote more of nmbd2 to use new structures
  74. +    - CLIX patches from Jason.J.Faultless@bechtel.btx400.co.uk
  75. +    - DirCacheFlush() bugfix from Michael Joosten
  76. +    <joost@ori.cadlab.de>. This bug explains a lot of the crashes.
  77. +    - fixed a bug in ChDir() that caused reversion to / in some
  78. +    situations
  79. +    - ipc fix from Magnus Hyllander <mhy@os.se>
  80.  
  81. +
  82.  ==========
  83.  todo:
  84.  
  85. @@ -1639,8 +1648,6 @@
  86.  
  87.  add masking to opendir?
  88.  
  89. -rename only if not rdonly?
  90. -
  91.  no refresh/reg of new IP? or send wack and challenge owner?
  92.  
  93.  new nmb.conf file
  94. @@ -1667,12 +1674,9 @@
  95.  
  96.  apparently WfWg doesn't like the password server stuff in 1.9.14. Why?
  97.  
  98. -UNRESOLVED PROBLEMS
  99. -===================
  100. +add "hide file = *.o" "hide dir = .Foo*" "show file = xx*" type options.
  101.  
  102. ----
  103.  ALLOW_PASSWORD_CHANGE only compiles/works on some systems
  104.  
  105. ----
  106.  weird foooooooo/open.exe bug on NT
  107.  
  108. diff -u -r --new-file last-version/source/client.c samba-1.9.14p4/source/client.c
  109. --- last-version/source/client.c    Tue Nov  7 13:59:55 1995
  110. +++ samba-1.9.14p4/source/client.c    Fri Nov 10 18:24:34 1995
  111. @@ -45,7 +45,7 @@
  112.  #define CLIENT_TIMEOUT (30*1000)
  113.  #define SHORT_TIMEOUT (5*1000)
  114.  
  115. -int name_type = ' ';
  116. +int name_type = 0x20;
  117.  int max_protocol = PROTOCOL_NT1;
  118.  
  119.  
  120. @@ -2749,7 +2749,7 @@
  121.        putip((char *)&dest_ip,inbuf+4);
  122.  
  123.        close_sockets();
  124. -      Client = open_socket_out(&dest_ip, port);
  125. +      Client = open_socket_out(SOCK_STREAM, &dest_ip, port);
  126.        if (Client == -1)
  127.          return False;
  128.  
  129. @@ -2971,7 +2971,7 @@
  130.        strcpy(pword,pass);      
  131.  
  132.  #ifdef SMB_PASSWD
  133. -      if (doencrypt) {
  134. +      if (doencrypt && *pass) {
  135.      DEBUG(3,("Using encrypted passwords\n"));
  136.      passlen = 24;
  137.      SMBencrypt(pass,cryptkey,pword);
  138. @@ -3090,7 +3090,7 @@
  139.      strcpy(pword,pass);
  140.  
  141.  #ifdef SMB_PASSWD
  142. -    if (doencrypt) {
  143. +    if (doencrypt && *pass) {
  144.        passlen=24;
  145.        SMBencrypt(pass,cryptkey,pword);      
  146.      }
  147. @@ -3577,7 +3577,7 @@
  148.        putip((char *)&dest_ip,(char *)hp->h_addr);
  149.      }
  150.  
  151. -  Client = open_socket_out(&dest_ip, port);
  152. +  Client = open_socket_out(SOCK_STREAM, &dest_ip, port);
  153.    if (Client == -1)
  154.      return False;
  155.  
  156. @@ -3931,9 +3931,8 @@
  157.      break;
  158.        case 'I':
  159.      {
  160. -      unsigned long a = interpret_addr(optarg);
  161. -      if (!a) exit(1);
  162. -      putip((char *)&dest_ip,(char *)&a);
  163. +      dest_ip = *interpret_addr2(optarg);
  164. +      if (zero_ip(dest_ip)) exit(1);
  165.        have_ip = True;
  166.      }
  167.      break;
  168. diff -u -r --new-file last-version/source/dir.c samba-1.9.14p4/source/dir.c
  169. --- last-version/source/dir.c    Tue Nov  7 12:46:56 1995
  170. +++ samba-1.9.14p4/source/dir.c    Fri Nov 10 11:18:03 1995
  171. @@ -671,6 +671,7 @@
  172.        next = entry->next;
  173.        if (entry->prev) entry->prev->next = entry->next;
  174.        if (entry->next) entry->next->prev = entry->prev;
  175. +      if (dir_cache == entry) dir_cache = entry->next; 
  176.        free(entry);
  177.      } else {
  178.        next = entry->next;
  179. diff -u -r --new-file last-version/source/getsmbpass.c samba-1.9.14p4/source/getsmbpass.c
  180. --- last-version/source/getsmbpass.c    Thu Sep 14 12:25:43 1995
  181. +++ samba-1.9.14p4/source/getsmbpass.c    Fri Nov 10 10:42:50 1995
  182. @@ -1,5 +1,3 @@
  183. -#if (defined(SMB_PASSWD) && defined(SMBGETPASS))
  184. -
  185.  /* Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc.
  186.  This file is part of the GNU C Library.
  187.  
  188. @@ -29,6 +27,9 @@
  189.  #endif
  190.  
  191.  #include "includes.h"
  192. +
  193. +#ifdef REPLACE_GETPASS
  194. +
  195.  
  196.  #include <termios.h>
  197.  
  198. diff -u -r --new-file last-version/source/includes.h samba-1.9.14p4/source/includes.h
  199. --- last-version/source/includes.h    Tue Nov  7 12:49:21 1995
  200. +++ samba-1.9.14p4/source/includes.h    Fri Nov 10 10:47:02 1995
  201. @@ -226,6 +226,7 @@
  202.  #include <utime.h>
  203.  #define NO_STRERROR
  204.  #endif
  205. +#define REPLACE_GETPASS
  206.  #endif
  207.  
  208.  
  209. @@ -257,6 +258,7 @@
  210.  #define USE_STATVFS
  211.  #define USE_GETCWD
  212.  #define USE_SETSID
  213. +#define REPLACE_GETPASS
  214.  #endif
  215.  
  216.  
  217. @@ -396,6 +398,8 @@
  218.  #define NO_FSYNC
  219.  #define USE_GETCWD
  220.  #define USE_SETSID
  221. +#define REPLACE_GETPASS
  222. +#define NO_GETRLIMIT
  223.  #endif    /* CLIX */
  224.  
  225.  
  226. @@ -753,6 +757,12 @@
  227.  /*******************************************************************
  228.  end of the platform specific sections
  229.  ********************************************************************/
  230. +
  231. +#ifdef REPLACE_GETPASS
  232. +extern char    *getsmbpass(char *);
  233. +#define getpass(s) getsmbpass(s)
  234. +#endif
  235. +
  236.  
  237.  #ifndef MAXINT
  238.  #define MAXINT ((((unsigned)1)<<(sizeof(int)*8-1))-1)
  239. diff -u -r --new-file last-version/source/ipc.c samba-1.9.14p4/source/ipc.c
  240. --- last-version/source/ipc.c    Mon Nov  6 16:54:58 1995
  241. +++ samba-1.9.14p4/source/ipc.c    Fri Nov 10 22:51:57 1995
  242. @@ -572,7 +572,7 @@
  243.    char *p = skip_string(str2,1);
  244.    char *QueueName = p;
  245.    int uLevel,cbBuf;
  246. -  int count;
  247. +  int count=0;
  248.    int snum;
  249.    char* str3;
  250.    struct pack_desc desc;
  251. @@ -604,6 +604,8 @@
  252.      }
  253.    }
  254.    
  255. +  if (snum < 0 || !VALID_SNUM(snum)) return(False);
  256. +
  257.    count = get_printqueue(snum,cnum,&queue,&status);
  258.    if (mdrcnt > 0) *rdata = REALLOC(*rdata,mdrcnt);
  259.    desc.base = *rdata;
  260. @@ -1041,7 +1043,7 @@
  261.  
  262.    SSVAL(*rparam,0,NERR_Success);
  263.  
  264. -  if (snum >= 0)
  265. +  if (snum >= 0 && VALID_SNUM(snum))
  266.      {
  267.        print_queue_struct *queue=NULL;
  268.        lpq_reset(snum);
  269. @@ -1108,7 +1110,7 @@
  270.      }
  271.    }
  272.  
  273. -  if (snum >= 0) {
  274. +  if (snum >= 0 && VALID_SNUM(snum)) {
  275.      print_queue_struct *queue=NULL;
  276.      int i, count;
  277.      lpq_reset(snum);
  278. @@ -1176,7 +1178,7 @@
  279.     
  280.    switch (function) {
  281.    case 0x6:    /* change job place in the queue, data gives the new place */
  282. -    if (snum >= 0)
  283. +    if (snum >= 0 && VALID_SNUM(snum))
  284.        {
  285.      print_queue_struct *queue=NULL;
  286.      int count;
  287. @@ -1672,6 +1674,8 @@
  288.    snum = (unsigned int)uJobId >> 8; /*## valid serice number??*/
  289.    job = uJobId & 0xFF;
  290.  
  291. +  if (snum < 0 || !VALID_SNUM(snum)) return(False);
  292. +
  293.    count = get_printqueue(snum,cnum,&queue,&status);
  294.    for (i = 0; i < count; i++) {
  295.      if ((queue[i].job % 0xFF) == job) break;
  296. @@ -1742,6 +1746,8 @@
  297.        snum = lp_servicenumber(name);
  298.      }
  299.    }
  300. +
  301. +  if (snum < 0 || !VALID_SNUM(snum)) return(False);
  302.  
  303.    count = get_printqueue(snum,cnum,&queue,&status);
  304.    if (mdrcnt > 0) *rdata = REALLOC(*rdata,mdrcnt);
  305. diff -u -r --new-file last-version/source/local.h samba-1.9.14p4/source/local.h
  306. --- last-version/source/local.h    Sun Nov  5 12:37:52 1995
  307. +++ samba-1.9.14p4/source/local.h    Fri Nov 10 21:20:57 1995
  308. @@ -118,7 +118,6 @@
  309.  #define DPTR_IDLE_TIMEOUT (300)
  310.  #define SMBD_SELECT_LOOP (10)
  311.  #define NMBD_SELECT_LOOP (10)
  312. -#define BROWSE_INTERVAL (60)
  313.  #define REGISTRATION_INTERVAL (10*60)
  314.  #define NMBD_INETD_TIMEOUT (120)
  315.  #define NMBD_MAX_TTL (24*60*60)
  316. diff -u -r --new-file last-version/source/nameserv.h samba-1.9.14p4/source/nameserv.h
  317. --- last-version/source/nameserv.h    Tue Nov  7 22:17:38 1995
  318. +++ samba-1.9.14p4/source/nameserv.h    Fri Nov 10 19:08:49 1995
  319. @@ -26,6 +26,10 @@
  320.  #define NMB_PORT 137
  321.  #define DGRAM_PORT 138
  322.  
  323. +enum name_source {LMHOSTS, REGISTER, SELF, DNS};
  324. +enum node_type {B_NODE=0, P_NODE=1, M_NODE=2, NBDD_NODE=3};
  325. +enum packet_type {NMB_PACKET, DGRAM_PACKET};
  326. +
  327.  /* a netbios name structure */
  328.  struct nmb_name {
  329.    char name[17];
  330. @@ -33,6 +37,29 @@
  331.    int name_type;
  332.  };
  333.  
  334. +/* this is the structure used for the local netbios name list */
  335. +struct name_record
  336. +{
  337. +  struct name_record *next;
  338. +  struct name_record *prev;
  339. +  struct nmb_name name;
  340. +  time_t death_time;
  341. +  struct in_addr ip;
  342. +  BOOL unique;
  343. +  enum name_source source;
  344. +};
  345. +
  346. +/* this is used by the list of domains */
  347. +struct domain_record
  348. +{
  349. +  struct domain_record *next;
  350. +  struct domain_record *prev;
  351. +  fstring name;
  352. +  time_t lastannounce_time;
  353. +  int announce_interval;
  354. +  struct in_addr bcast_ip;
  355. +};
  356. +
  357.  /* a resource record */
  358.  struct res_rec {
  359.    struct nmb_name rr_name;
  360. @@ -76,25 +103,27 @@
  361.  };
  362.  
  363.  
  364. -/* a datagram - a simple structure at first, it would be good to parse
  365. -   it properly later */
  366. +/* a datagram - this normally contains SMB data in the data[] array */
  367.  struct dgram_packet {
  368.    struct {
  369. -    int res;
  370. -    int id;
  371. -    struct in_addr ip;
  372. -    int port;
  373. -    int length;
  374. -    int res2;
  375. -    struct nmb_name source_name;
  376. -    struct nmb_name dest_name;
  377. +    int msg_type;
  378. +    struct {
  379. +      enum node_type node_type;
  380. +      BOOL first;
  381. +      BOOL more;
  382. +    } flags;
  383. +    int dgm_id;
  384. +    struct in_addr source_ip;
  385. +    int source_port;
  386. +    int dgm_length;
  387. +    int packet_offset;
  388.    } header;
  389. -  int smbsize;
  390. -  char smb_data[MAX_DGRAM_SIZE];
  391. +  struct nmb_name source_name;
  392. +  struct nmb_name dest_name;
  393. +  int datasize;
  394. +  char data[MAX_DGRAM_SIZE];
  395.  };
  396.  
  397. -enum packet_type {NMB_PACKET, DGRAM_PACKET};
  398. -
  399.  /* define a structure used to queue packets. this will be a linked
  400.   list of nmb packets */
  401.  struct packet_struct
  402. @@ -128,3 +157,16 @@
  403.  struct packet_struct *read_packet(int fd,enum packet_type packet_type);
  404.  BOOL send_packet(struct packet_struct *p);
  405.  struct packet_struct *receive_packet(int fd,enum packet_type type,int timeout);
  406. +void make_nmb_name(struct nmb_name *n,char *name,int type,char *this_scope);
  407. +BOOL name_query(int fd,char *name,int name_type,
  408. +               BOOL bcast,BOOL recurse,
  409. +               struct in_addr to_ip, struct in_addr *ip,void (*fn)());
  410. +BOOL name_status(int fd,char *name,int name_type,BOOL recurse,
  411. +            struct in_addr to_ip,char *master,void (*fn)());
  412. +BOOL send_udp_dgram(int fd,char *buf,int len,
  413. +               char *srcname,char *dstname,
  414. +               int src_type,int dest_type,
  415. +               struct in_addr dest_ip,
  416. +               struct in_addr src_ip);
  417. +
  418. +
  419. diff -u -r --new-file last-version/source/nameserv2.c samba-1.9.14p4/source/nameserv2.c
  420. --- last-version/source/nameserv2.c    Tue Nov  7 22:37:02 1995
  421. +++ samba-1.9.14p4/source/nameserv2.c    Fri Nov 10 21:20:49 1995
  422. @@ -25,75 +25,38 @@
  423.  
  424.  
  425.  static void queue_packet(struct packet_struct *packet);
  426. -
  427. +void process(void);
  428. +static void dump_names(void);
  429.  
  430.  extern int DEBUGLEVEL;
  431.  
  432. -/* the list of network interfaces */
  433. -struct net_interface *interfaces = NULL;
  434. -
  435.  extern pstring debugf;
  436. -extern int DEBUGLEVEL;
  437.  
  438.  extern pstring scope;
  439.  
  440. -static int browse_interval = BROWSE_INTERVAL;
  441. -
  442. -static BOOL dns_serve = False;
  443. -static BOOL CanRecurse = True;
  444. +extern BOOL CanRecurse;
  445.  
  446. -extern struct in_addr lastip;
  447. -extern int lastport;
  448.  extern struct in_addr myip;
  449.  extern struct in_addr bcast_ip;
  450.  extern struct in_addr Netmask;
  451.  extern pstring myhostname;
  452.  static pstring host_file;
  453.  static pstring myname="";
  454. -static pstring lookup="";
  455. +
  456.  static int ClientNMB=-1;
  457.  static int ClientDGRAM=-1;
  458. -enum name_sources {LMHOSTS, REGISTER, SELF, DNS};
  459. -
  460. -/* this is the structure used for the local netbios name table */
  461. -typedef struct
  462. -{
  463. -  time_t start_time;
  464. -  int ttl;
  465. -  struct in_addr ip;
  466. -  struct in_addr master_ip;
  467. -  BOOL found_master;
  468. -  BOOL valid;
  469. -  BOOL isgroup;
  470. -  BOOL unicast;
  471. -  char name[100];
  472. -  int type;
  473. -  int count;  
  474. -  enum name_sources source;
  475. -} name_struct;
  476. -
  477. -
  478. -static int num_names=0;
  479. -static name_struct *names = NULL;
  480. -
  481. -#define NAMEVALID(i) names[i].valid
  482. -#define ISGROUP(i) (names[i].isgroup)
  483.  
  484. -void process(void);
  485. +static struct name_record *namelist = NULL;
  486. +static struct domain_record *domainlist = NULL;
  487.  
  488.  /* are we running as a daemon ? */
  489.  static BOOL is_daemon = False;
  490.  
  491. -/* machine comment */
  492. +/* machine comment for host announcements */
  493.  static pstring comment="";
  494.  
  495.  extern pstring user_socket_options;
  496.  
  497. -static void add_group_name(char *name);
  498. -static void add_host_name(char *name,int type,struct in_addr *ip);
  499. -static void dump_names(void);
  500. -
  501. -
  502.  static BOOL got_bcast = False;
  503.  static BOOL got_myip = False;
  504.  static BOOL got_nmask = False;
  505. @@ -150,680 +113,323 @@
  506.  /****************************************************************************
  507.    true if two netbios names are equal
  508.  ****************************************************************************/
  509. -static BOOL name_equal(char *s1,char *s2,int type1,int type2)
  510. +static BOOL name_equal(struct nmb_name *n1,struct nmb_name *n2)
  511.  {
  512. -  char n1[20],n2[20];
  513. -
  514. -  if (type1 != type2) return(False);
  515. -
  516. -  StrnCpy(n1,s1,15);
  517. -  StrnCpy(n2,s2,15);
  518. -
  519. -  trim_string(n1,NULL," ");
  520. -  trim_string(n2,NULL," ");
  521. +  if (n1->name_type != n2->name_type) return(False);
  522.  
  523. -  return(strequal(n1,n2));
  524. +  return(strequal(n1->name,n2->name) && strequal(n1->scope,n2->scope));
  525.  }
  526.  
  527.  /****************************************************************************
  528. -add a netbios name
  529. -****************************************************************************/
  530. -static int add_name(void)
  531. +  add a netbios name into the namelist
  532. +  **************************************************************************/
  533. +static void add_name(struct name_record *n)
  534.  {
  535. -  int i;
  536. -
  537. -  for (i=0;i<num_names;i++)
  538. -    if (!names[i].valid)
  539. -      break;
  540. +  struct name_record *n2;
  541.  
  542. -  if (i==num_names) {
  543. -    name_struct *n;
  544. -    if (num_names == 0)    
  545. -      n = (name_struct *)malloc(sizeof(name_struct));
  546. -    else
  547. -      n = (name_struct *)realloc(names,sizeof(name_struct)*(num_names+1));
  548. -    if (!n) {
  549. -      DEBUG(0,("Can't malloc more names space!\n"));
  550. -      return(-1);
  551. -    }
  552. -    i = num_names;
  553. -    num_names++;
  554. -    names = n;
  555. +  if (!namelist) {
  556. +    namelist = n;
  557. +    n->prev = NULL;
  558. +    n->next = NULL;
  559. +    return;
  560.    }
  561.  
  562. -  bzero(&names[i],sizeof(names[i]));
  563. -
  564. -  return(i);
  565. -}
  566. -
  567. -/****************************************************************************
  568. -find a name
  569. -****************************************************************************/
  570. -static int find_name(char *s,int type,BOOL groups)
  571. -{
  572. -  int i;
  573. -  time_t t = time(NULL);
  574. +  for (n2 = namelist; n2->next; n2 = n2->next) ;
  575.  
  576. -  for (i=0;i<num_names;i++)
  577. -    if (names[i].valid && (groups || !ISGROUP(i)))
  578. -      {
  579. -    if ((names[i].ttl > 0) && (t > (names[i].start_time + names[i].ttl)))
  580. -      names[i].valid = False;
  581. -    else
  582. -      {
  583. -        if (name_equal(s,names[i].name,type,names[i].type)) {
  584. -          return(i);
  585. -        }
  586. -      }
  587. -      }
  588. -  return -1;
  589. +  n2->next = n;
  590. +  n->next = NULL;
  591. +  n->prev = n2;
  592.  }
  593.  
  594. -
  595.  /****************************************************************************
  596. -check names, and change any 0 IPs to myip
  597. -****************************************************************************/
  598. -static void check_names(void)
  599. +  add a domain into the list
  600. +  **************************************************************************/
  601. +static void add_domain(struct domain_record *d)
  602.  {
  603. -  int i;
  604. -  int group_count=0;
  605. -
  606. -  /* add the magic __SAMBA__ name */
  607. -  add_host_name("__SAMBA__",0x20,&myip);
  608. -  add_host_name("__SAMBA__",0x0,&myip);
  609. -
  610. -  for (i=0;i<num_names;i++)
  611. -    if (names[i].valid) {
  612. -      if (ISGROUP(i)) group_count++;
  613. -    }
  614. +  struct domain_record *d2;
  615.  
  616. -  if (group_count == 0)
  617. -    add_group_name(WORKGROUP);
  618. +  if (!domainlist) {
  619. +    domainlist = d;
  620. +    d->prev = NULL;
  621. +    d->next = NULL;
  622. +    return;
  623. +  }
  624.  
  625. +  for (d2 = domainlist; d2->next; d2 = d2->next) ;
  626.  
  627. -  for (i=0;i<num_names;i++)
  628. -    if (names[i].valid && strequal((char *)inet_ntoa(names[i].ip),"0.0.0.0"))
  629. -      names[i].ip = (ISGROUP(i)?bcast_ip:myip);
  630. +  d2->next = d;
  631. +  d->next = NULL;
  632. +  d->prev = d2;
  633.  }
  634.  
  635. -
  636.  /****************************************************************************
  637. -dump a copy of the name table
  638. -****************************************************************************/
  639. -static void dump_names(void)
  640. +  remove a name from the namelist. The pointer must be an element just 
  641. +  retrieved
  642. +  **************************************************************************/
  643. +static void remove_name(struct name_record *n)
  644.  {
  645. -  int i;
  646. -  DEBUG(3,("Dump of local name table\n"));
  647. -  for (i=0;i<num_names;i++)
  648. -    if (names[i].valid) {
  649. -      DEBUG(3,("%s %s %d %s",
  650. -           names[i].name,inet_ntoa(names[i].ip),
  651. -           names[i].ttl,BOOLSTR(names[i].isgroup)));
  652. -      if (names[i].found_master) 
  653. -    DEBUG(3,(" %s",inet_ntoa(names[i].master_ip)));
  654. -      DEBUG(3,("\n"));
  655. -    }
  656. +  struct name_record *nlist = namelist;
  657. +  while (nlist && nlist != n) nlist = nlist->next;
  658. +  if (nlist) {
  659. +    if (nlist->next) nlist->next->prev = nlist->prev;
  660. +    if (nlist->prev) nlist->prev->next = nlist->next;
  661. +    free(nlist);
  662. +  }
  663.  }
  664.  
  665. -
  666.  /****************************************************************************
  667. -load a netbios hosts file
  668. -****************************************************************************/
  669. -static void load_hosts_file(char *fname)
  670. +  find a name in the namelist matching some criterion
  671. +  **************************************************************************/
  672. +static struct name_record *find_name(struct nmb_name *n)
  673.  {
  674. -  int i;
  675. -  FILE *f = fopen(fname,"r");
  676. -  pstring line;
  677. -  if (!f) 
  678. -    {
  679. -      DEBUG(2,("Not using non-existant lmhosts file %s\n",fname));
  680. -      return;
  681. -    }
  682. -
  683. -  while (!feof(f))
  684. -    {
  685. -      if (!fgets_slash(line,sizeof(pstring),f)) continue;
  686. -      
  687. -      if (*line == '#') continue;
  688. -
  689. -      {
  690. -    string ip="",name="",flags="",extra="";
  691. -    unsigned long a;
  692. -    char *ptr;
  693. -    int count = 0;
  694. -    ptr = line;
  695. -    if (next_token(&ptr,ip,NULL)) ++count;
  696. -    if (next_token(&ptr,name,NULL)) ++count;
  697. -    if (next_token(&ptr,flags,NULL)) ++count;
  698. -    if (next_token(&ptr,extra,NULL)) ++count;
  699. -
  700. -    if (count <= 0) continue;
  701. -
  702. -    if (count > 0 && count < 2)
  703. -      {
  704. -        DEBUG(0,("Ill formed hosts line [%s]\n",line));        
  705. -        continue;
  706. -      }
  707. +  struct name_record *ret;
  708. +  for (ret = namelist; ret; ret = ret->next)
  709. +    if (name_equal(&ret->name,n)) return(ret);
  710.  
  711. -    i = add_name();
  712. -    if (i < 0) 
  713. -      {
  714. -        fclose(f);
  715. -        return;
  716. -      }
  717. +  return(NULL);
  718. +}
  719.  
  720. -    a = interpret_addr(ip);
  721. -    putip((char *)&names[i].ip,(char *)&a);
  722. +/****************************************************************************
  723. +  dump a copy of the name table
  724. +  **************************************************************************/
  725. +static void dump_names(void)
  726. +{
  727. +  time_t t = time(NULL);
  728. +  struct name_record *n;
  729. +  struct domain_record *d;
  730.  
  731. -    names[i].valid = True;
  732. -    names[i].source = LMHOSTS;
  733. +  DEBUG(3,("Dump of local name table:\n"));
  734.  
  735. -    StrnCpy(names[i].name,name,15);
  736. -    if (strchr(flags,'G') || strchr(flags,'S'))
  737. -      names[i].isgroup = True;
  738. -    if (strchr(flags,'M') && !ISGROUP(i))
  739. -      strcpy(myname,name);
  740. -    if (strchr(flags,'U'))
  741. -      names[i].unicast = True;
  742. -    if (names[i].isgroup) 
  743. -      names[i].type = 0xF0; /* hopefully invalid */
  744. -    else
  745. -      names[i].type = 0x20;
  746. -      }      
  747. +  for (n = namelist; n; n = n->next) {
  748. +    DEBUG(3,("%s(%x) %s TTL=%d Unique=%s\n",
  749. +         n->name.name,n->name.name_type,
  750. +         inet_ntoa(n->ip),
  751. +         n->death_time?n->death_time-t:0,
  752. +         BOOLSTR(n->unique)));
  753.      }
  754.  
  755. -  fclose(f);
  756. +  DEBUG(3,("\nDump of domain list:\n"));
  757. +  for (d = domainlist; d; d = d->next)
  758. +    DEBUG(3,("%s %s\n",d->name,inet_ntoa(d->bcast_ip)));
  759.  }
  760.  
  761.  
  762.  /****************************************************************************
  763. -add a netbios group name
  764. -****************************************************************************/
  765. -static void add_group_name(char *name)
  766. +  add a permanent host entry to the name list
  767. +  ****************************************************************************/
  768. +static struct name_record *add_host_entry(char *name,int type,BOOL unique,int ttl,
  769. +                      enum name_source source,
  770. +                      struct in_addr ip)
  771.  {
  772. -  int i = add_name();
  773. -  if (i < 0) 
  774. -    return;
  775. +  struct name_record *n = (struct name_record *)malloc(sizeof(*n));
  776. +  struct name_record *n2=NULL;
  777.  
  778. -  bzero((char *)&names[i].ip,sizeof(names[i].ip));
  779. +  if (!n) return(NULL);
  780.  
  781. -  strcpy(names[i].name,name);
  782. -  names[i].isgroup = True;
  783. -  names[i].valid = True;
  784. -  names[i].type = 0xF0;
  785. -  names[i].source = SELF;
  786. -}
  787. +  bzero((char *)n,sizeof(*n));
  788.  
  789. -/****************************************************************************
  790. -add a host name
  791. -****************************************************************************/
  792. -static void add_host_name(char *name,int type,struct in_addr *ip)
  793. -{
  794. -  int i;
  795. +  make_nmb_name(&n->name,name,type,scope);
  796. +  if ((n2=find_name(&n->name))) {
  797. +    free(n);
  798. +    n = n2;
  799. +  }
  800.  
  801. -  if (find_name(name,type,True) >= 0) return;
  802. +  if (ttl) n->death_time = time(NULL)+ttl;
  803. +  n->ip = ip;
  804. +  n->unique = unique;
  805. +  n->source = source;
  806. +  
  807. +  if (!n2) add_name(n);
  808.  
  809. -  i = add_name();
  810. -  if (i < 0) 
  811. -    return;
  812. +  DEBUG(3,("Added host entry %s(%x) at %s ttl=%d unique=%s\n",
  813. +       name,type,inet_ntoa(ip),ttl,BOOLSTR(unique)));
  814.  
  815. -  names[i].ip = *ip;
  816. -  strcpy(names[i].name,name);
  817. -  names[i].valid = True;
  818. -  names[i].start_time = time(NULL);
  819. -  names[i].ttl = 0;
  820. -  names[i].type = type;
  821. -  names[i].source = SELF;
  822. +  return(n);
  823.  }
  824.  
  825. +
  826.  /****************************************************************************
  827. -work out the length of a nmb message
  828. -****************************************************************************/
  829. -static int nmb_len(char *buf)
  830. +  add a domain entry
  831. +  ****************************************************************************/
  832. +static struct domain_record *add_domain_entry(char *name,struct in_addr ip)
  833.  {
  834. -int i;
  835. -int ret = 12;
  836. -char *p = buf;
  837. -int qdcount = RSVAL(buf,4);
  838. -int ancount = RSVAL(buf,6);
  839. -int nscount = RSVAL(buf,8);
  840. -int arcount = RSVAL(buf,10);
  841. -
  842. -/* check for insane qdcount values? */
  843. -if (qdcount > 100 || qdcount < 0)
  844. -  {
  845. -    DEBUG(6,("Invalid qdcount? qdcount=%d\n",qdcount));
  846. -    return(0);
  847. -  }
  848. -
  849. -for (i=0;i<qdcount;i++)
  850. -  {
  851. -    p = buf + ret;
  852. -    ret += name_len(p) + 4;
  853. -  }
  854. -
  855. -for (i=0;i<(ancount + nscount + arcount);i++)
  856. -  {
  857. -    int rdlength;
  858. -    p = buf + ret;
  859. -    ret += name_len(p) + 8;
  860. -    p = buf + ret;
  861. -    rdlength = RSVAL(p,0);
  862. -    ret += rdlength + 2;
  863. -  }
  864. +  struct domain_record *d = (struct domain_record *)malloc(sizeof(*d));
  865.  
  866. -return(ret);
  867. -}
  868. +  if (!d) return(NULL);
  869.  
  870. -/****************************************************************************
  871. -receive a name message. timeout is in milliseconds
  872. -****************************************************************************/
  873. -static int receive_nmb(char *buffer,int timeout)
  874. -{
  875. -  int ret = read_max_udp(ClientNMB,buffer,sizeof(pstring),timeout);
  876. +  bzero((char *)d,sizeof(*d));
  877.  
  878. -  if (ret < 0)
  879. -    {
  880. -      DEBUG(0,("No bytes from client\n"));
  881. -      if (!is_daemon)
  882. -    {
  883. -      close_sockets();
  884. -      exit(0);
  885. -    }
  886. -    }
  887. +  StrnCpy(d->name,name,sizeof(d->name)-1);
  888. +  d->bcast_ip = ip;
  889.    
  890. -  if (ret <= 1)
  891. -    return 0;
  892. +  add_domain(d);
  893.  
  894. -  log_in(buffer,ret);
  895. +  ip = *interpret_addr2("255.255.255.255");
  896. +  if (name[0] != '*') add_host_entry(name,0x1e,False,0,SELF,ip);      
  897.  
  898. -  DEBUG(3,("received packet from (%s) nmb_len=%d len=%d\n",
  899. -    inet_ntoa(lastip),nmb_len(buffer),ret));
  900. +  DEBUG(3,("Added domain entry %s at %s\n",
  901. +       name,inet_ntoa(ip)));
  902.  
  903. -  return(ret);
  904. +  return(d);
  905.  }
  906.  
  907. +
  908.  /****************************************************************************
  909. -send a name message
  910. -****************************************************************************/
  911. -static BOOL send_nmb(char *buf, int len, struct in_addr *ip,int port)
  912. +  add the magic samba names, useful for finding samba servers
  913. +  **************************************************************************/
  914. +static void add_my_names(void)
  915.  {
  916. -  BOOL ret;
  917. -  struct sockaddr_in sock_out;
  918. +  struct in_addr ip = *interpret_addr2("0.0.0.0");
  919.  
  920. -  /* set the address and port */
  921. -  bzero((char *)&sock_out,sizeof(sock_out));
  922. -  putip((char *)&sock_out.sin_addr,(char *)ip);
  923. -  sock_out.sin_port = htons( port );
  924. -  sock_out.sin_family = AF_INET;
  925. -  
  926. -  /* log the packet */
  927. -  log_out(buf,len);
  928. -
  929. -  if (DEBUGLEVEL > 0)
  930. -    DEBUG(3,("sending a packet of len %d to (%s) on port 137 of type DGRAM\n",
  931. -      len,inet_ntoa(*ip)));
  932. -    
  933. -  /* send it */
  934. -  ret = (sendto(ClientNMB,buf,len,0,(struct sockaddr *)&sock_out,sizeof(sock_out)) >= 0);
  935. -
  936. -  if (!ret)
  937. -    DEBUG(0,("Send packet failed. ERRNO=%d\n",errno));
  938. -
  939. -  return(ret);
  940. +  add_host_entry("__SAMBA__",0x20,True,0,SELF,ip);
  941. +  add_host_entry("__SAMBA__",0x0,True,0,SELF,ip);
  942. +  add_host_entry(myname,0x20,True,0,SELF,ip);
  943. +  add_host_entry(myname,0x0,True,0,SELF,ip);
  944. +  add_host_entry(myname,0x3,True,0,SELF,ip);
  945. +  if (!domainlist)
  946. +    add_domain_entry(WORKGROUP,bcast_ip);
  947.  }
  948.  
  949. -/*******************************************************************
  950. -check if an IP is on my net
  951. -********************************************************************/
  952. -static BOOL is_mynet(struct in_addr ip)
  953. -{
  954. -  unsigned int net1,net2,nmask,subnet1,subnet2;
  955. -
  956. -  nmask   = *(unsigned int *)&Netmask;
  957. -  net1    = (*(unsigned int *)&myip);
  958. -  subnet1 = net1 & nmask;
  959. -  net2    = (*(unsigned int *)&ip);
  960. -  subnet2 = net2 & nmask;
  961. -        
  962. -  return((net1 != net2) && (subnet1 == subnet2));
  963. -}
  964.  
  965. -/****************************************************************************
  966. -interpret a node status response
  967. -****************************************************************************/
  968. -static void interpret_node_status(char *inbuf, char *master)
  969. +/*******************************************************************
  970. +  delete old names from the namelist
  971. +  ******************************************************************/
  972. +static void housekeeping(void)
  973.  {
  974. -  int level = master?3:0;
  975. -  char *p = inbuf + 12 + name_len(inbuf+12) + 10;
  976. -  int numnames = CVAL(p,0);
  977. -  DEBUG(level,("received %d names\n",numnames));
  978. +  time_t lastrun=0;
  979. +  time_t t = time(NULL);
  980. +  struct name_record *n;
  981. +  struct name_record *next;
  982.  
  983. -  p += 1;
  984. -  while (numnames--)
  985. -    {
  986. -      char qname[17];
  987. -      int type;
  988. -      fstring flags="";
  989. -      StrnCpy(qname,p,15);
  990. -      type = CVAL(p,15);
  991. -      p += 16;
  992. -
  993. -      if (p[0] & 0x80) strcat(flags,"<GROUP> ");
  994. -      if (p[0] & 0x60 == 0) strcat(flags,"B ");
  995. -      if (p[0] & 0x60 == 1) strcat(flags,"P ");
  996. -      if (p[0] & 0x60 == 2) strcat(flags,"M ");
  997. -      if (p[0] & 0x60 == 3) strcat(flags,"_ ");
  998. -      if (p[0] & 0x10) strcat(flags,"<DEREGISTERING> ");
  999. -      if (p[0] & 0x08) strcat(flags,"<CONFLICT> ");
  1000. -      if (p[0] & 0x04) strcat(flags,"<ACTIVE> ");
  1001. -      if (p[0] & 0x02) strcat(flags,"<PERMANENT> ");
  1002. +  if (!lastrun) lastrun = t;
  1003. +  if (t < lastrun + 5*60) return;
  1004.  
  1005. -      if (master && type == 0x1d) {
  1006. -    StrnCpy(master,qname,15);
  1007. -      }
  1008. -      
  1009. -      DEBUG(level,("\t%s (type=0x%x)\t%s\n",qname,type,flags));
  1010. -      p+=2;
  1011. +  lastrun = t;
  1012. +
  1013. +  for (n = namelist; n; n = next) {
  1014. +    if (n->death_time && n->death_time < t) {
  1015. +      DEBUG(3,("Removing dead name %s(%x)\n",
  1016. +           n->name.name,n->name.name_type));
  1017. +      next = n->next;
  1018. +      if (n->prev) n->prev->next = n->next;
  1019. +      if (n->next) n->next->prev = n->prev;
  1020. +      if (namelist == n) namelist = n->next; 
  1021. +      free(n);
  1022. +    } else {
  1023. +      next = n->next;
  1024.      }
  1025. -  DEBUG(level,("num_good_sends=%d num_good_receives=%d\n",
  1026. -           IVAL(p,20),IVAL(p,24)));
  1027. +  }
  1028.  }
  1029.  
  1030. -
  1031.  /****************************************************************************
  1032. -show a nmb message
  1033. +load a netbios hosts file
  1034.  ****************************************************************************/
  1035. -static void show_nmb(char *inbuf)
  1036. +static void load_hosts_file(char *fname)
  1037.  {
  1038. -  int i,l;
  1039. -  int name_trn_id = RSVAL(inbuf,0);
  1040. -  int opcode = (CVAL(inbuf,2) >> 3) & 0xF;
  1041. -  int nm_flags = ((CVAL(inbuf,2) & 0x7) << 4) + (CVAL(inbuf,3)>>4);
  1042. -  int rcode = CVAL(inbuf,3) & 0xF;
  1043. -  int qdcount = RSVAL(inbuf,4);
  1044. -  int ancount = RSVAL(inbuf,6);
  1045. -  int nscount = RSVAL(inbuf,8);
  1046. -  int arcount = RSVAL(inbuf,10);
  1047. -  char name[100];
  1048. -
  1049. -  if (DEBUGLEVEL < 3) return;
  1050. -
  1051. -  DEBUG(3,("\nPACKET INTERPRETATION\n"));
  1052. -
  1053. -  if (opcode == 5 && ((nm_flags & ~1) == 0x10) && rcode == 0)
  1054. -    DEBUG(3,("NAME REGISTRATION REQUEST (%s)\n",nm_flags&1?"Broadcast":"Unicast"));
  1055. -
  1056. -  if (opcode == 5 && ((nm_flags & ~1) == 0x00) && rcode == 0)
  1057. -    DEBUG(3,("NAME OVERWRITE REQUEST AND DEMAND (%s)\n",nm_flags&1?"Broadcast":"Unicast"));
  1058. -  
  1059. -  if (opcode == 9 && ((nm_flags & ~1) == 0x00) && rcode == 0)
  1060. -    DEBUG(3,("NAME REFRESH REQUEST (%s)\n",nm_flags&1?"Broadcast":"Unicast"));
  1061. -
  1062. -  if (opcode == 8)
  1063. -    DEBUG(3,("NAME REFRESH (%s)\n",nm_flags&1?"Broadcast":"Unicast"));
  1064. -  
  1065. -  if (opcode == 5 && nm_flags == 0x58 && rcode == 0)
  1066. -    DEBUG(3,("POSITIVE NAME REGISTRATION RESPONSE\n"));
  1067. -  
  1068. -  if (opcode == 5 && nm_flags == 0x58 && rcode != 0 && rcode != 7)
  1069. -    DEBUG(3,("NEGATIVE NAME REGISTRATION RESPONSE\n"));
  1070. -  
  1071. -  if (opcode == 5 && nm_flags == 0x50 && rcode == 0)
  1072. -    DEBUG(3,("END-NODE CHALLENGE REGISTRATION RESPONSE\n"));
  1073. -  
  1074. -  if (opcode == 5 && nm_flags == 0x58 && rcode != 0 && rcode == 7)
  1075. -    DEBUG(3,("NAME CONFLICT DEMAND\n"));
  1076. -  
  1077. -  if (opcode == 6 && (nm_flags&~1) == 0x00 && rcode == 0)
  1078. -    DEBUG(3,("NAME RELEASE REQUEST & DEMAND (%s)\n",nm_flags&1?"Broadcast":"Unicast"));
  1079. -  
  1080. -  if (opcode == 6 && (nm_flags&~1) == 0x40 && rcode == 0)
  1081. -    DEBUG(3,("POSITIVE NAME RELEASE RESPONSE\n"));
  1082. -  
  1083. -  if (opcode == 6 && (nm_flags&~1) == 0x40 && rcode != 0)
  1084. -    DEBUG(3,("NEGATIVE NAME RELEASE RESPONSE\n"));
  1085. -  
  1086. -  if (opcode == 0 && (nm_flags&~1) == 0x10 && rcode == 0)
  1087. -    DEBUG(3,("NAME QUERY REQUEST (%s)\n",nm_flags&1?"Broadcast":"Unicast"));
  1088. -  
  1089. -  if (opcode == 0 && (nm_flags&~0x28) == 0x50 && rcode == 0)
  1090. -    DEBUG(3,("POSITIVE NAME QUERY RESPONSE\n"));
  1091. -  
  1092. -  if (opcode == 0 && (nm_flags&~0x08) == 0x50 && rcode != 0)
  1093. -    DEBUG(3,("NEGATIVE NAME QUERY RESPONSE\n"));
  1094. -  
  1095. -  if (opcode == 0 && nm_flags == 0x10 && rcode == 0)
  1096. -    DEBUG(3,("REDIRECT NAME QUERY RESPONSE\n"));
  1097. -
  1098. -  if (opcode == 7 && nm_flags == 0x80 && rcode == 0)
  1099. -    DEBUG(3,("WAIT FOR ACKNOWLEDGEMENT RESPONSE\n"));
  1100. -  
  1101. -  if (opcode == 0 && (nm_flags&~1) == 0x00 && rcode == 0)
  1102. -    DEBUG(3,("NODE STATUS REQUEST (%s)\n",nm_flags&1?"Broadcast":"Unicast"));
  1103. -
  1104. -  if (opcode == 0 && nm_flags == 0x40 && rcode == 0)
  1105. -    {
  1106. -      DEBUG(3,("NODE STATUS RESPONSE\n"));
  1107. -      interpret_node_status(inbuf,NULL);
  1108. -    }
  1109. -  
  1110. -  
  1111. -  DEBUG(3,("name_trn_id=0x%x\nopcode=0x%x\nnm_flags=0x%x\nrcode=0x%x\n",
  1112. -    name_trn_id,opcode,nm_flags,rcode));
  1113. -  DEBUG(3,("qdcount=%d\nancount=%d\nnscount=%d\narcount=%d\n",
  1114. -    qdcount,ancount,nscount,arcount));
  1115. -
  1116. -  l = 12;
  1117. -  for (i=0;i<qdcount;i++)
  1118. -    {
  1119. -      int type,class;
  1120. -      DEBUG(3,("QUESTION %d\n",i));
  1121. -      name_extract(inbuf,l,name);
  1122. -      l += name_len(inbuf+l);
  1123. -      type = RSVAL(inbuf+l,0);
  1124. -      class = RSVAL(inbuf+l,2);
  1125. -      l += 4;
  1126. -      DEBUG(3,("\t%s\n\ttype=0x%x\n\tclass=0x%x\n",name,type,class));
  1127. -    }
  1128. +  FILE *f = fopen(fname,"r");
  1129. +  pstring line;
  1130. +  if (!f) {
  1131. +    DEBUG(2,("Can't open lmhosts file %s\n",fname));
  1132. +    return;
  1133. +  }
  1134.  
  1135. -  for (i=0;i<(ancount + nscount + arcount);i++)
  1136. +  while (!feof(f))
  1137.      {
  1138. -      int type,class,ttl,rdlength;
  1139. -      DEBUG(3,("RESOURCE %d\n",i));
  1140. -      name_extract(inbuf,l,name);
  1141. -      l += name_len(inbuf + l);
  1142. -      type = RSVAL(inbuf+l,0);
  1143. -      class = RSVAL(inbuf+l,2);
  1144. -      ttl = RIVAL(inbuf+l,4);
  1145. -      rdlength = RSVAL(inbuf+l,8);
  1146. -      l += 10 + rdlength;
  1147. -      DEBUG(3,("\t%s\n\ttype=0x%x\n\tclass=0x%x\n",name,type,class));
  1148. -      DEBUG(3,("\tttl=%d\n\trdlength=%d\n",ttl,rdlength));
  1149. -    }
  1150. +      if (!fgets_slash(line,sizeof(pstring),f)) continue;
  1151. +      
  1152. +      if (*line == '#') continue;
  1153.  
  1154. -  DEBUG(3,("\n"));
  1155. -  
  1156. -}
  1157. +      {
  1158. +    BOOL group=False;
  1159. +    string ip="",name="",flags="",extra="";
  1160. +    char *ptr;
  1161. +    int count = 0;
  1162. +    struct in_addr ipaddr;
  1163. +    enum name_source source = LMHOSTS;
  1164.  
  1165. +    ptr = line;
  1166.  
  1167. -/****************************************************************************
  1168. -do a netbios name status to a host
  1169. -****************************************************************************/
  1170. -static BOOL name_status(char *name,int type,struct in_addr to_ip,char *master)
  1171. -{
  1172. -  pstring inbuf,outbuf;
  1173. -  static uint16 name_trn_id = 0x4262;
  1174. -  char *p;
  1175. -  int retries = 2;
  1176. -  int retry_time = 5000;
  1177. -  struct timeval tval;
  1178. +    if (next_token(&ptr,ip,NULL)) ++count;
  1179. +    if (next_token(&ptr,name,NULL)) ++count;
  1180. +    if (next_token(&ptr,flags,NULL)) ++count;
  1181. +    if (next_token(&ptr,extra,NULL)) ++count;
  1182.  
  1183. -  bzero(inbuf,sizeof(inbuf));
  1184. -  bzero(outbuf,sizeof(outbuf));
  1185. +    if (count <= 0) continue;
  1186.  
  1187. -  name_trn_id += getpid() % 100;
  1188. -  name_trn_id = (name_trn_id % 10000);
  1189. +    if (count > 0 && count < 2)
  1190. +      {
  1191. +        DEBUG(0,("Ill formed hosts line [%s]\n",line));        
  1192. +        continue;
  1193. +      }
  1194.  
  1195. -  RSSVAL(outbuf,0,name_trn_id);
  1196. -  CVAL(outbuf,2) = 0;
  1197. -  CVAL(outbuf,3) = 0x0;
  1198. -  RSSVAL(outbuf,4,1);
  1199. -  RSSVAL(outbuf,6,0);
  1200. -  RSSVAL(outbuf,8,0);
  1201. -  RSSVAL(outbuf,10,0);  
  1202. -  p = outbuf+12;
  1203. -  name_mangle(name,p,type);
  1204. -  p += name_len(p);
  1205. -  RSSVAL(p,0,0x21);
  1206. -  RSSVAL(p,2,0x1);
  1207. -  p += 4;
  1208. +    if (strchr(flags,'G') || strchr(flags,'S'))
  1209. +      group = True;
  1210.  
  1211. -  show_nmb(outbuf);
  1212. +    if (strchr(flags,'M') && !group) {
  1213. +      source = SELF;
  1214. +      strcpy(myname,name);
  1215. +    }
  1216.  
  1217. -  GetTimeOfDay(&tval);
  1218. +    ipaddr = *interpret_addr2(ip);
  1219.  
  1220. -  if (!send_nmb(outbuf,nmb_len(outbuf), &to_ip, NMB_PORT))
  1221. -    return False;
  1222. -  
  1223. -  while (1)
  1224. -    {
  1225. -      struct timeval tval2;
  1226. -      GetTimeOfDay(&tval2);
  1227. -      if (TvalDiff(&tval,&tval2) > retry_time) {
  1228. -    if (!retries) break;
  1229. -    if (!send_nmb(outbuf,nmb_len(outbuf), &to_ip, NMB_PORT))
  1230. -      return False;
  1231. -    GetTimeOfDay(&tval);
  1232. -    retries--;    
  1233. -      }
  1234. -      
  1235. -      if (receive_nmb(inbuf,90))
  1236. -    {
  1237. -      int rec_name_trn_id = RSVAL(inbuf,0);
  1238. -      int rcode = CVAL(inbuf,3) & 0xF;
  1239. -      int response = (CVAL(inbuf,2)>>7);
  1240. -      int qdcount = RSVAL(inbuf,4);
  1241. -      int ancount = RSVAL(inbuf,6);
  1242. -
  1243. -      show_nmb(inbuf);
  1244. -      
  1245. -      /* is it a positive response to our request? */
  1246. -      if (response && (rec_name_trn_id == name_trn_id)) {
  1247. -        if (rcode==0 && ancount==1 && qdcount==0) {
  1248. -          interpret_node_status(inbuf, master);
  1249. -          return(True);
  1250. -        }
  1251. -        return(False);
  1252. -      }
  1253. +    if (group) {
  1254. +      add_domain_entry(name,ipaddr);
  1255. +    } else {
  1256. +      add_host_entry(name,0x20,True,0,source,ipaddr);
  1257.      }
  1258. +      }
  1259.      }
  1260.  
  1261. -  DEBUG(0,("No status response (this is not unusual)\n"));
  1262. -
  1263. -  return(False);
  1264. +  fclose(f);
  1265.  }
  1266.  
  1267. -/****************************************************************************
  1268. -construct a host announcement unicast
  1269. -****************************************************************************/
  1270. -static BOOL send_udp_dgram(char *buf,int len,
  1271. -             char *srcname,char *dstname,
  1272. -             int src_type,int dest_type,
  1273. -             struct in_addr dest_ip)
  1274. +/*******************************************************************
  1275. +  check if 2 IPs are on the same net
  1276. +  we will assume the local netmask, although this could be wrong XXXX
  1277. +  ******************************************************************/
  1278. +static BOOL same_net(struct in_addr ip1,struct in_addr ip2)
  1279.  {
  1280. -  pstring outbuf;
  1281. -  char *p,*p2;
  1282. -  static int id=0;
  1283. -  char tmp[4];
  1284. -  struct sockaddr_in sock_out;
  1285. -
  1286. -  bzero(outbuf,sizeof(outbuf));
  1287. -  RSSVAL(outbuf,0,0x1102); /* what is this? */
  1288. -  RSSVAL(outbuf,2,++id); 
  1289. -  putip(outbuf+4,(void *)&myip);
  1290. -  RSSVAL(outbuf,8,DGRAM_PORT);
  1291. -  RSSVAL(outbuf,12,0);
  1292. -  p = outbuf + 14;
  1293. -  p += name_mangle(srcname,p,src_type);
  1294. -  p += name_mangle(dstname,p,dest_type);
  1295. -
  1296. -  /* now setup the smb part */
  1297. -  p -= 4;
  1298. -  memcpy(tmp,p,4);
  1299. -  set_message(p,17,17 + len,True);
  1300. -  memcpy(p,tmp,4);
  1301. -
  1302. -  CVAL(p,smb_com) = SMBtrans;
  1303. -  SSVAL(p,smb_vwv1,len);
  1304. -  SSVAL(p,smb_vwv11,len);
  1305. -  SSVAL(p,smb_vwv12,86);
  1306. -  SSVAL(p,smb_vwv13,3);
  1307. -  SSVAL(p,smb_vwv14,1);
  1308. -  SSVAL(p,smb_vwv15,1);
  1309. -  SSVAL(p,smb_vwv16,2);
  1310. -  p2 = smb_buf(p);
  1311. -  strcpy(p2,"\\MAILSLOT\\BROWSE");
  1312. -  p2 = skip_string(p2,1);
  1313. -
  1314. -  memcpy(p2,buf,len);
  1315. -  p2 += len;
  1316. -
  1317. -  len = PTR_DIFF(p2,outbuf);
  1318. -  RSSVAL(outbuf,10,len);
  1319. -
  1320. -
  1321. -  /* set the address and port */
  1322. -  bzero((char *)&sock_out,sizeof(sock_out));
  1323. -  putip((char *)&sock_out.sin_addr,(char *)&dest_ip);
  1324. -  sock_out.sin_port = htons(DGRAM_PORT);
  1325. -  sock_out.sin_family = AF_INET;
  1326. -  
  1327. -  /* log the packet */
  1328. -  log_out(outbuf,len);
  1329. -  
  1330. -  /* send it */
  1331. -  if (sendto(ClientDGRAM,outbuf,len,0,
  1332. -         (struct sockaddr *)&sock_out,sizeof(sock_out)) < 0) {
  1333. -    DEBUG(3,("Sendto failed errno=%d (%s)\n",errno,strerror(errno)));
  1334. -    return(False);
  1335. -  } 
  1336. +  unsigned int net1,net2,nmask;
  1337.  
  1338. -  return(True);
  1339. +  putip((char *)&nmask,(char *)&Netmask);
  1340. +  putip((char *)&net1,(char *)&ip1);
  1341. +  putip((char *)&net2,(char *)&ip2);
  1342. +        
  1343. +  return((net1 & nmask) == (net2 & nmask));
  1344.  }
  1345.  
  1346. +
  1347.  /****************************************************************************
  1348. -construct a host announcement unicast
  1349. -****************************************************************************/
  1350. -static void announce_host(int i,char *my_name,char *Comment)
  1351. +  construct a host announcement unicast
  1352. +  **************************************************************************/
  1353. +static void announce_host(struct domain_record *d,char *my_name,char *Comment)
  1354.  {
  1355. -  static int announce_interval = 1;
  1356. -  char *group = names[i].name;
  1357. -  struct in_addr dest_ip = names[i].ip;
  1358. +  time_t t = time(NULL);
  1359.    pstring outbuf;
  1360.    char *p;
  1361.  
  1362. -  names[i].count++;
  1363. -
  1364. -  if ((names[i].count % announce_interval) != 0) return;
  1365. +  /* announce every minute at first then progress to every 15 mins */
  1366. +  if (d->lastannounce_time && 
  1367. +      (t - d->lastannounce_time) < d->announce_interval)
  1368. +    return;
  1369.  
  1370. -  if (announce_interval < 2) announce_interval++;
  1371. +  if (d->announce_interval < 15*60) d->announce_interval += 60;
  1372. +  d->lastannounce_time = t;
  1373.  
  1374. -  DEBUG(2,("Sending host announcement to %s for group %s\n",
  1375. -       inet_ntoa(dest_ip),group));       
  1376. +  DEBUG(2,("Sending host announcement to %s for workgroup %s\n",
  1377. +       inet_ntoa(d->bcast_ip),d->name));       
  1378.  
  1379.    if (!*Comment) Comment = "NoComment";
  1380.    if (!*my_name) my_name = "NoName";
  1381. -  if (!*group) group = "NoGroup";
  1382.  
  1383. -  if (strlen(Comment) > 47) Comment[47] = 0;  
  1384. +  if (strlen(Comment) > 43) Comment[43] = 0;  
  1385.  
  1386.    bzero(outbuf,sizeof(outbuf));
  1387.    p = outbuf;
  1388.    CVAL(p,0) = 1; /* host announce */
  1389.    SSVAL(p,1,0x6006); /* update count?? */
  1390.    CVAL(p,3) = 0xEA; /* res1 */ 
  1391. -  SSVAL(p,4,announce_interval);
  1392. +  SSVAL(p,4,d->announce_interval);
  1393.    p += 6;
  1394.    StrnCpy(p,my_name,16);
  1395.    strupper(p);
  1396. @@ -837,361 +443,141 @@
  1397.    strcpy(p,Comment);
  1398.    p += strlen(p)+1;
  1399.  
  1400. -  send_udp_dgram(outbuf,PTR_DIFF(p,outbuf),my_name,group,0,0x1d,dest_ip);
  1401. -}
  1402. -
  1403. -
  1404. -
  1405. -/****************************************************************************
  1406. -send a name registration packet
  1407. -****************************************************************************/
  1408. -static void send_registration(char *name,int name_type,struct in_addr dest_ip,struct in_addr ip,BOOL refresh,int ttl)
  1409. -{
  1410. -  char *p;
  1411. -  static int t = 0x176;
  1412. -  pstring outbuf;
  1413. -  bzero(outbuf,sizeof(outbuf));
  1414. -  /* send a registration request */
  1415. -  RSSVAL(outbuf,0,t++);
  1416. -  if (refresh)
  1417. -    CVAL(outbuf,2) = (0<<7) | (9<<3) | 0;
  1418. -  else
  1419. -    CVAL(outbuf,2) = (0<<7) | (5<<3) | 1;
  1420. -    
  1421. -  CVAL(outbuf,3) = (1<<4);
  1422. -  RSSVAL(outbuf,4,1);
  1423. -  RSSVAL(outbuf,6,0);
  1424. -  RSSVAL(outbuf,8,0);
  1425. -  RSSVAL(outbuf,10,1);  
  1426. -  p = outbuf+12;
  1427. -  name_mangle(name,p,name_type);
  1428. -  p += name_len(p);
  1429. -  RSSVAL(p,0,0x20);
  1430. -  RSSVAL(p,2,0x1);
  1431. -  p += 4;
  1432. -  RSSVAL(p,0,12);
  1433. -  CVAL(p,0) = CVAL(p,0) | 0xC0;
  1434. -  p += 2;
  1435. -  RSSVAL(p,0,0x20);
  1436. -  RSSVAL(p,2,0x1);
  1437. -  p += 4;  
  1438. -  RSIVAL(p,0,ttl);
  1439. -
  1440. -  RSSVAL(p,4,6);
  1441. -  RSSVAL(p,6,0);  
  1442. -  p += 8;
  1443. -  putip(p,&ip);  
  1444. -  p += 4;
  1445. -
  1446. -  DEBUG(2,("Sending a name registration request\n"));
  1447. -  if (DEBUGLEVEL > 2)
  1448. -    show_nmb(outbuf);
  1449. -
  1450. -  send_nmb(outbuf,PTR_DIFF(p,outbuf),&dest_ip,NMB_PORT);
  1451. -}
  1452. -
  1453. -/*******************************************************************
  1454. -find a master browser
  1455. -********************************************************************/
  1456. -BOOL find_master(char *name1,struct in_addr ip,struct in_addr *ipout)
  1457. -{
  1458. -  int type = 0x1d;
  1459. -  fstring name;
  1460. -  BOOL ret;
  1461. -  strcpy(name,name1);
  1462. -  if (strequal(name,"*")) {
  1463. -    strcpy(name,"\001\002__MSBROWSE__\002");
  1464. -    type = 1;
  1465. -  }
  1466. -  ret = name_query(name,type,True,False,ip,ipout);
  1467. -  if (!ret) return(False);
  1468. -  if (type != 1) return(True);
  1469. -
  1470. -  name_status(name,type,*ipout,name1);
  1471. -  return(name1[0] != '*');
  1472. +  send_udp_dgram(ClientDGRAM,outbuf,PTR_DIFF(p,outbuf),
  1473. +         my_name,d->name,0,0x1d,d->bcast_ip,myip);
  1474.  }
  1475.  
  1476. -/****************************************************************************
  1477. -process a workgroup announce frame
  1478. -****************************************************************************/
  1479. -static void process_workgroup_announce(char *group,struct in_addr ip)
  1480. -{
  1481. -  int i;
  1482. -  for (i=0;i<num_names;i++)
  1483. -    if (names[i].valid) {
  1484. -      if (names[i].name[0] == '*') {
  1485. -    StrnCpy(names[i].name,group,15);
  1486. -    names[i].master_ip = ip;
  1487. -    names[i].found_master = True;
  1488. -    names[i].count=0;
  1489. -    announce_host(i,myname,comment);
  1490. -    return;
  1491. -      }
  1492. -      if (names[i].isgroup && name_equal(names[i].name,group,0,0)) {
  1493. -    int j;
  1494. -    for (j=i;j<num_names;j++)
  1495. -      if (names[j].valid && names[j].isgroup && names[i].found_master && 
  1496. -          name_equal(names[i].name,group,0,0)) return;
  1497. -    names[i].master_ip = ip;
  1498. -    names[i].found_master = True;
  1499. -    names[i].count=0;
  1500. -    announce_host(i,myname,comment);
  1501. -    return;
  1502. -      }
  1503. -    }
  1504. -}
  1505. -
  1506.  
  1507.  /****************************************************************************
  1508.  process a browse frame
  1509.  ****************************************************************************/
  1510. -static void process_browse_packet(char *buf,int len)
  1511. +static void process_browse_packet(struct packet_struct *p,char *buf,int len)
  1512.  {
  1513. -  char *p;
  1514. +  /* don't actually do anything with these at the moment */
  1515. +#if 0
  1516.    int command = CVAL(buf,0);
  1517.    switch (command) {
  1518. -  case 0xc: /* workgroup announcement */
  1519. +  case 0xc: /* domain announcement */
  1520.      {
  1521.        fstring group;
  1522. -      p = buf + 6;
  1523. -      StrnCpy(group,p,15);
  1524. +      StrnCpy(group,buf+6,15);
  1525.        DEBUG(2,("Got workgroup announce for %s (%s)\n",
  1526.             group,inet_ntoa(lastip)));
  1527. -      process_workgroup_announce(group,lastip);
  1528. +      process_workgroup_announce(p,group);
  1529.        break;
  1530.      }
  1531.    }
  1532. -
  1533. +#endif
  1534.  }
  1535.  
  1536. +
  1537.  /****************************************************************************
  1538.  process udp 138 datagrams
  1539.  ****************************************************************************/
  1540. -static void process_dgram(void)
  1541. +static void process_dgram(struct packet_struct *p)
  1542.  {
  1543. -  pstring inbuf;
  1544. +  char *buf;
  1545.    int len;
  1546. -  while (read_max_udp(ClientDGRAM,inbuf,sizeof(inbuf),1) > 4) {
  1547. -    char *p = inbuf;
  1548. -    len = RSVAL(inbuf,10);
  1549. -    p += 14;
  1550. -    p += name_len(p);
  1551. -    p += name_len(p);
  1552. -    p -= 4;
  1553. -    if (CVAL(p,smb_com) != SMBtrans) continue;
  1554. -    if (!strequal(smb_buf(p),"\\MAILSLOT\\BROWSE")) continue;
  1555. -    len = SVAL(p,smb_vwv11);
  1556. -    p = smb_base(p) + SVAL(p,smb_vwv12);
  1557. -    if (len <= 0) continue;
  1558. -    process_browse_packet(p,len);
  1559. +  struct dgram_packet *dgram = &p->packet.dgram;
  1560. +
  1561. +  if (dgram->header.msg_type != 0x10 &&
  1562. +      dgram->header.msg_type != 0x11 &&
  1563. +      dgram->header.msg_type != 0x12) {
  1564. +    /* don't process error packets etc yet */
  1565. +    return;
  1566.    }
  1567. -}
  1568.  
  1569. -/****************************************************************************
  1570. -a hook for registration of my own names
  1571. -****************************************************************************/
  1572. -static void do_registration_hook(void)
  1573. -{
  1574. -  static int count = 0;
  1575. -  static time_t last_t=0;
  1576. -  time_t t = time(NULL);
  1577. -  
  1578. -  if (last_t && (t-last_t)<REGISTRATION_INTERVAL) return;
  1579. -  last_t = t;
  1580. -  
  1581. -  send_registration(myname,0x20,bcast_ip,myip,count>0,300000);
  1582. -  count++;
  1583. +  buf = &dgram->data[0];
  1584. +  buf -= 4; /* XXXX for the pseudo tcp length - 
  1585. +           someday I need to get rid of this */
  1586. +
  1587. +  if (CVAL(buf,smb_com) != SMBtrans) return;
  1588. +  if (!strequal(smb_buf(buf),"\\MAILSLOT\\BROWSE")) return;
  1589. +  len = SVAL(buf,smb_vwv11);
  1590. +  buf = smb_base(buf) + SVAL(buf,smb_vwv12);
  1591. +  if (len <= 0) return;
  1592. +  process_browse_packet(p,buf,len);
  1593.  }
  1594.  
  1595. -/****************************************************************************
  1596. -a hook for browsing handling - called every BROWSE_INTERVAL secs
  1597. -****************************************************************************/
  1598. -static void do_browse_hook(void)
  1599. +/*******************************************************************
  1600. +  find a workgroup using the specified broadcast
  1601. +  ******************************************************************/
  1602. +static BOOL find_workgroup(char *name,struct in_addr ip)
  1603.  {
  1604. -  static BOOL first = True;
  1605. -  int i;
  1606. -  static time_t last_t=0;
  1607. -  time_t t = time(NULL);
  1608. -  
  1609. -  if (last_t && (t-last_t)<browse_interval) return;
  1610. -  last_t = t;
  1611. -
  1612. -  for (i=0;i<num_names;i++)
  1613. -    {
  1614. -      BOOL old_found_master = names[i].found_master;
  1615. +  fstring name1;
  1616. +  BOOL ret;
  1617. +  struct in_addr ipout;
  1618.  
  1619. -      if (!NAMEVALID(i) || !ISGROUP(i)) continue;
  1620. +  strcpy(name1,"\001\002__MSBROWSE__\002");
  1621.  
  1622. -      if (names[i].found_master) {
  1623. -    struct in_addr ip2;
  1624. -    announce_host(i,myname,comment);
  1625. -
  1626. -    if (!name_query(names[i].name,0x1d,True,False,
  1627. -            names[i].master_ip,
  1628. -            &ip2)) {
  1629. -      DEBUG(2,("%s Master browser at %s failed to respond\n",
  1630. -           timestring(),
  1631. -           inet_ntoa(names[i].master_ip)));
  1632. -      names[i].found_master = False;
  1633. -    } else {
  1634. -      names[i].master_ip = ip2;
  1635. -    }
  1636. -      }
  1637. +  ret = name_query(ClientNMB,name1,0x1,True,False,ip,&ipout,queue_packet);
  1638. +  if (!ret) return(False);
  1639.  
  1640. -      if (!names[i].found_master) {
  1641. -    struct in_addr ip2;
  1642. -    names[i].found_master = find_master(names[i].name,names[i].ip,&ip2);
  1643. -
  1644. -    if (names[i].found_master) {
  1645. -      names[i].master_ip = ip2;
  1646. -      DEBUG(1,("%s New master browser for %s at %s\n",
  1647. -           timestring(),
  1648. -           names[i].name,inet_ntoa(names[i].master_ip)));
  1649. -      names[i].count = 0;
  1650. -      announce_host(i,myname,comment);
  1651. -    }
  1652. -      }
  1653. +  name_status(ClientNMB,name1,0x1,False,ipout,name,queue_packet);
  1654.  
  1655. -      if (!names[i].found_master) {
  1656. -    int level = (old_found_master||first)?1:2;
  1657. -    DEBUG(level,("%s Failed to find a master browser for %s using %s\n",
  1658. -             timestring(),
  1659. -             names[i].name,inet_ntoa(names[i].ip)));
  1660. -      }
  1661. -    }
  1662. -  first = False;
  1663. +  if (name[0] != '*') {
  1664. +    DEBUG(2,("Found workgroup %s on broadcast %s\n",name,inet_ntoa(ip)));
  1665. +  } else {
  1666. +    DEBUG(3,("Failed to find workgroup %s on broadcast %s\n",name,inet_ntoa(ip)));
  1667. +  }
  1668. +  return(name[0] != '*');
  1669.  }
  1670.  
  1671.  
  1672.  /****************************************************************************
  1673. -  do a netbios name query to find someones IP
  1674. -  ****************************************************************************/
  1675. -static BOOL name_query(char *name,int name_type, BOOL bcast,BOOL recurse,
  1676. -               struct in_addr to_ip, struct in_addr *ip)
  1677. +  a hook for browsing handling - called every minute
  1678. +  **************************************************************************/
  1679. +static void do_browse_hook(void)
  1680.  {
  1681. -  BOOL found=False;
  1682. -  static uint16 name_trn_id = 0;
  1683. -  int retries = 3;
  1684. -  int retry_time = bcast?250:5000;
  1685. -  struct timeval tval;
  1686. -  struct packet_struct p;
  1687. -  struct packet_struct *p2;
  1688. -  struct nmb_packet *nmb = &p.packet.nmb;
  1689. -
  1690. -  bzero((char *)&p,sizeof(p));
  1691. -
  1692. -  if (!name_trn_id) name_trn_id = (time(NULL)%0x7FFF) + (getpid()%100);
  1693. -  name_trn_id = (name_trn_id+1) % 0x7FFF;
  1694. -
  1695. -  nmb->header.name_trn_id = name_trn_id;
  1696. -  nmb->header.opcode = 0;
  1697. -  nmb->header.response = False;
  1698. -  nmb->header.nm_flags.bcast = bcast;
  1699. -  nmb->header.nm_flags.recursion_available = CanRecurse;
  1700. -  nmb->header.nm_flags.recursion_desired = recurse;
  1701. -  nmb->header.nm_flags.trunc = False;
  1702. -  nmb->header.nm_flags.authoritative = False;
  1703. -  nmb->header.rcode = 0;
  1704. -  nmb->header.qdcount = 1;
  1705. -  nmb->header.ancount = 0;
  1706. -  nmb->header.nscount = 0;
  1707. -  nmb->header.arcount = 0;
  1708. -
  1709. -  strcpy(nmb->question.question_name.name,name);
  1710. -  strupper(nmb->question.question_name.name);
  1711. -  nmb->question.question_name.name_type = name_type;
  1712. -  strcpy(nmb->question.question_name.scope,scope);
  1713. -
  1714. -  nmb->question.question_type = 0x20;
  1715. -  nmb->question.question_class = 0x1;
  1716. -
  1717. -  p.ip = to_ip;
  1718. -  p.port = NMB_PORT;
  1719. -  p.fd = ClientNMB;
  1720. -  p.timestamp = time(NULL);
  1721. -  p.packet_type = NMB_PACKET;
  1722. -
  1723. -  GetTimeOfDay(&tval);
  1724. -
  1725. -  if (!send_packet(&p)) 
  1726. -    return(False);
  1727. -
  1728. -  retries--;
  1729. -
  1730. -  while (1)
  1731. -    {
  1732. -      struct timeval tval2;
  1733. -      GetTimeOfDay(&tval2);
  1734. -      if (TvalDiff(&tval,&tval2) > retry_time) {
  1735. -    if (!retries) break;
  1736. -    if (!found && !send_packet(&p))
  1737. -      return False;
  1738. -    GetTimeOfDay(&tval);
  1739. -    retries--;
  1740. -      }
  1741. +  struct domain_record *d;
  1742.  
  1743. -      if ((p2=receive_packet(ClientNMB,NMB_PACKET,90)))
  1744. -    {     
  1745. -      struct nmb_packet *nmb2 = &p2->packet.nmb;
  1746. -      if (nmb->header.name_trn_id != nmb2->header.name_trn_id ||
  1747. -          !nmb2->header.response) {
  1748. -        /* its not for us - deal with it later */
  1749. -        queue_packet(p2);
  1750. -        continue;
  1751. -      }
  1752. -      
  1753. -      if (nmb2->header.opcode != 0 ||
  1754. -          nmb2->header.nm_flags.bcast ||
  1755. -          nmb2->header.rcode ||
  1756. -          !nmb2->header.ancount) {
  1757. -        /* XXXX what do we do with this? could be a redirect, but
  1758. -           we'll discard it for the moment */
  1759. -        free_packet(p2);
  1760. -        continue;
  1761. -      }
  1762. +  for (d = domainlist; d; d = d->next) {
  1763. +    /* if the ip address is 0 then set to the broadcast */
  1764. +    if (zero_ip(d->bcast_ip)) d->bcast_ip = bcast_ip;
  1765.  
  1766. -      putip((char *)ip,&nmb2->answers->rdata[2]);
  1767. -      DEBUG(2,("Got a positive name query response from %s",
  1768. -           inet_ntoa(p2->ip)));
  1769. -      DEBUG(2,(" (%s)\n",inet_ntoa(*ip)));
  1770. -      found=True; retries=0;
  1771. -    }
  1772. +    /* if the workgroup is '*' then find a workgroup to be part of */
  1773. +    if (d->name[0] == '*') {
  1774. +      if (!find_workgroup(d->name,d->bcast_ip)) continue;
  1775. +      add_host_entry(d->name,0x1e,False,0,SELF,*interpret_addr2("255.255.255.255"));
  1776.      }
  1777.  
  1778. -  return(found);
  1779. +    announce_host(d,myname,comment);
  1780. +  }
  1781.  }
  1782.  
  1783.  
  1784. +
  1785.  /****************************************************************************
  1786.  reply to a name release
  1787.  ****************************************************************************/
  1788.  static void reply_name_release(struct packet_struct *p)
  1789.  {
  1790.    struct nmb_packet *nmb = &p->packet.nmb;
  1791. -  char *qname = nmb->question.question_name.name;
  1792. -  BOOL wildcard = (qname[0] == '*'); 
  1793. -  int name_type = nmb->question.question_name.name_type;
  1794. -  int nb_flags = nmb->additional->rdata[0];
  1795.    struct packet_struct p2;
  1796.    struct nmb_packet *nmb2;
  1797.    struct res_rec answer_rec;
  1798.    struct in_addr ip;
  1799. -  BOOL release_ok=False;
  1800. -  int reason=5;
  1801. -  int n;
  1802. -
  1803. -  if (wildcard) return;
  1804. +  int rcode=0;
  1805. +  int nb_flags = nmb->additional->rdata[0];
  1806.  
  1807.    putip((char *)&ip,&nmb->additional->rdata[2]);  
  1808.  
  1809. -  n = find_name(qname,name_type,True);
  1810. -  if (n>=0 && names[n].source == REGISTER &&
  1811. -      !memcmp((char *)&ip,(char *)&names[n].ip,sizeof(ip))) {
  1812. -    release_ok = True;
  1813. -    names[n].valid = False;
  1814. +  {
  1815. +    struct name_record *n = find_name(&nmb->question.question_name);
  1816. +    if (n && n->unique && n->source == REGISTER &&
  1817. +    ip_equal(ip,n->ip)) {
  1818. +      remove_name(n); n = NULL;
  1819. +    }
  1820. +
  1821. +    /* XXXX under what conditions should we reject the removal?? */
  1822.    }
  1823.  
  1824. -  /* Send a POSITIVE NAME RELEASE RESPONSE */
  1825. +  DEBUG(3,("Name release on name %s(%x) rcode=%d\n",
  1826. +       nmb->question.question_name.name,
  1827. +       nmb->question.question_name.name_type,rcode));
  1828. +
  1829. +
  1830. +  /* Send a NAME RELEASE RESPONSE */
  1831.    p2 = *p;
  1832.    nmb2 = &p2.packet.nmb;
  1833.  
  1834. @@ -1204,7 +590,7 @@
  1835.    nmb2->header.ancount = 1;
  1836.    nmb2->header.nscount = 0;
  1837.    nmb2->header.arcount = 0;
  1838. -  nmb2->header.rcode = release_ok?0:reason;
  1839. +  nmb2->header.rcode = rcode;
  1840.  
  1841.    nmb2->answers = &answer_rec;
  1842.    bzero((char *)nmb2->answers,sizeof(*nmb2->answers));
  1843. @@ -1231,50 +617,59 @@
  1844.    char *qname = nmb->question.question_name.name;
  1845.    BOOL wildcard = (qname[0] == '*'); 
  1846.    BOOL bcast = nmb->header.nm_flags.bcast;
  1847. -  int name_type = nmb->question.question_name.name_type;
  1848.    int ttl = nmb->additional->ttl;
  1849. +  int name_type = nmb->question.question_name.name_type;
  1850.    int nb_flags = nmb->additional->rdata[0];
  1851.    struct packet_struct p2;
  1852.    struct nmb_packet *nmb2;
  1853.    struct res_rec answer_rec;
  1854.    struct in_addr ip;
  1855. +  BOOL group = (nb_flags&0x80)?True:False;
  1856. +  int rcode = 0;  
  1857.  
  1858.    if (wildcard) return;
  1859.  
  1860.    putip((char *)&ip,&nmb->additional->rdata[2]);
  1861.  
  1862. -  if ((nb_flags&0x80) == 0 && (name_type != 0x1d)) {
  1863. -    int n = find_name(qname,name_type,True);
  1864. -    if (ttl==0) ttl = NMBD_MAX_TTL;
  1865. -    ttl = MIN(ttl,NMBD_MAX_TTL);
  1866. +  if (group) {
  1867. +    /* apparently we should return 255.255.255.255 for group queries (email from MS) */
  1868. +    ip = *interpret_addr2("255.255.255.255");
  1869. +  }
  1870.  
  1871. -    if (n>=0 && names[n].source != REGISTER && names[n].source != DNS)
  1872. -      return;
  1873. +  {
  1874. +    struct name_record *n = find_name(&nmb->question.question_name);
  1875.  
  1876. -    if (n<0)
  1877. -      n = add_name();
  1878. -    if (n<0) return;
  1879. -
  1880. -    bzero(&names[n],sizeof(names[n]));
  1881. -
  1882. -    StrnCpy(names[n].name,qname,15);
  1883. -    names[n].type = name_type;
  1884. -    names[n].unicast = !dns_serve || is_mynet(ip);
  1885. -    names[n].ip = ip;
  1886. -    names[n].valid = True;
  1887. -    names[n].ttl = ttl;
  1888. -    names[n].source = REGISTER;
  1889. -    names[n].start_time = p->timestamp;
  1890. +    if (n) {
  1891. +      if (!group && !ip_equal(ip,n->ip)) {
  1892. +    /* check if the previous owner still wants it, 
  1893. +       if so reject the registration, otherwise change the owner 
  1894. +       and refresh */
  1895. +    /* XXXXXX not done yet */
  1896. +    rcode = 5;
  1897. +      } else {
  1898. +    /* refresh the name */
  1899. +    n->death_time = ttl?p->timestamp + ttl:0;
  1900. +      }
  1901. +    } else {
  1902. +      /* add the name to our database */
  1903. +      n = add_host_entry(qname,name_type,!group,ttl,REGISTER,ip);
  1904. +    }
  1905.    }
  1906.  
  1907.    if (bcast) return;
  1908.  
  1909. -  /* Send a POSITIVE NAME REGISTRATION RESPONSE */
  1910. +  DEBUG(3,("Name registration for name %s(%x) at %s rcode=%d\n",
  1911. +       nmb->question.question_name.name,
  1912. +       nmb->question.question_name.name_type,
  1913. +       inet_ntoa(ip),rcode));
  1914. +
  1915. +  /* Send a NAME REGISTRATION RESPONSE */
  1916.    /* a lot of fields get copied from the query. This gives us the IP
  1917.       and port the reply will be sent to etc */
  1918.    p2 = *p;
  1919.    nmb2 = &p2.packet.nmb;
  1920.  
  1921. +  nmb2->header.opcode = 5; 
  1922.    nmb2->header.response = True;
  1923.    nmb2->header.nm_flags.bcast = False;
  1924.    nmb2->header.nm_flags.recursion_available = CanRecurse;
  1925. @@ -1284,6 +679,7 @@
  1926.    nmb2->header.ancount = 1;
  1927.    nmb2->header.nscount = 0;
  1928.    nmb2->header.arcount = 0;
  1929. +  nmb2->header.rcode = rcode;
  1930.  
  1931.    nmb2->answers = &answer_rec;
  1932.    bzero((char *)nmb2->answers,sizeof(*nmb2->answers));
  1933. @@ -1292,10 +688,6 @@
  1934.    nmb2->answers->rr_type = nmb->question.question_type;
  1935.    nmb2->answers->rr_class = nmb->question.question_class;
  1936.  
  1937. -  /* we want them to refresh in case we die */
  1938. -  if (!ttl) ttl = 15*60;
  1939. -  ttl = MIN(ttl,15*60);
  1940. -
  1941.    nmb2->answers->ttl = ttl; 
  1942.    nmb2->answers->rdlength = 6;
  1943.    nmb2->answers->rdata[0] = nb_flags;
  1944. @@ -1313,22 +705,23 @@
  1945.    struct nmb_packet *nmb = &p->packet.nmb;
  1946.    char *qname = nmb->question.question_name.name;
  1947.    BOOL wildcard = (qname[0] == '*'); 
  1948. -  int name_type = nmb->question.question_name.name_type;
  1949.    struct packet_struct p2;
  1950.    struct nmb_packet *nmb2;
  1951.    struct res_rec answer_rec;
  1952.    char *buf;
  1953. -  int count,i;
  1954. +  int count;
  1955. +  int rcode = 0;
  1956. +  struct name_record *n = find_name(&nmb->question.question_name);
  1957.  
  1958. -  if (!wildcard) {
  1959. -    i = find_name(qname,name_type,False);
  1960. +  if (!wildcard && (!n || n->source != SELF)) 
  1961. +    return;
  1962.  
  1963. -    if (i < 0)
  1964. -      return;
  1965. -    if (names[i].source != SELF && names[i].source != LMHOSTS)
  1966. -      return;
  1967. -  }
  1968.  
  1969. +  DEBUG(3,("Name status for name %s(%x) rcode=%d\n",
  1970. +       nmb->question.question_name.name,
  1971. +       nmb->question.question_name.name_type,
  1972. +       rcode));
  1973. +
  1974.    /* Send a POSITIVE NAME STATUS RESPONSE */
  1975.    /* a lot of fields get copied from the query. This gives us the IP
  1976.       and port the reply will be sent to etc */
  1977. @@ -1345,6 +738,7 @@
  1978.    nmb2->header.ancount = 1;
  1979.    nmb2->header.nscount = 0;
  1980.    nmb2->header.arcount = 0;
  1981. +  nmb2->header.rcode = rcode;
  1982.  
  1983.    nmb2->answers = &answer_rec;
  1984.    bzero((char *)nmb2->answers,sizeof(*nmb2->answers));
  1985. @@ -1355,8 +749,8 @@
  1986.    nmb2->answers->rr_class = nmb->question.question_class;
  1987.    nmb2->answers->ttl = 0; /* XXX what ttl to answer with? */
  1988.  
  1989. -  for (count=0,i=0;i<num_names;i++)
  1990. -    if (names[i].valid) count++;
  1991. +  for (count=0, n = namelist ; n; n = n->next) count++;
  1992. +
  1993.    count = MIN(count,400/18); /* XXXX hack, we should calculate exactly
  1994.                  how many will fit */
  1995.  
  1996. @@ -1365,20 +759,19 @@
  1997.    SCVAL(buf,0,count);
  1998.    buf += 1;
  1999.  
  2000. -  for (i=0;i<num_names && count>0;i++)
  2001. -    if (names[i].valid)
  2002. -      {
  2003. -    bzero(buf,18);
  2004. -    strcpy(buf,names[i].name);
  2005. -    strupper(buf);
  2006. -    buf[15] = names[i].type;
  2007. -    buf += 16;
  2008. -    buf[0] = 0x4; /* active */
  2009. -    if (strequal(names[i].name,myname)) buf[0] |= 0x2; /* permanent */
  2010. -    if (ISGROUP(i)) buf[0] |= 0x80; /* group */
  2011. -    buf += 2;
  2012. -    count--;
  2013. -      }
  2014. +  for (n = namelist ; n; n = n->next) 
  2015. +    {
  2016. +      bzero(buf,18);
  2017. +      strcpy(buf,n->name.name);
  2018. +      strupper(buf);
  2019. +      buf[15] = n->name.name_type;
  2020. +      buf += 16;
  2021. +      buf[0] = 0x4; /* active */
  2022. +      if (strequal(n->name.name,myname)) buf[0] |= 0x2; /* permanent */
  2023. +      if (!n->unique) buf[0] |= 0x80; /* group */
  2024. +      buf += 2;
  2025. +      count--;
  2026. +    }
  2027.  
  2028.    /* we should fill in more fields of the statistics structure */
  2029.    bzero(buf,46);
  2030. @@ -1412,61 +805,69 @@
  2031.    struct packet_struct p2;
  2032.    struct nmb_packet *nmb2;
  2033.    struct res_rec answer_rec;
  2034. +  int ttl=0;
  2035. +  int rcode=0;
  2036. +  BOOL unique = True;
  2037. +
  2038. +  if (wildcard)
  2039. +    retip = myip;
  2040.  
  2041.    if (!wildcard) {
  2042. -    int i = find_name(qname,name_type,False);
  2043. +    struct name_record *n = find_name(&nmb->question.question_name);
  2044.  
  2045. -    if (i < 0)
  2046. -      i = find_name(qname,name_type,True);
  2047. -    
  2048. -    if (i >= 0)
  2049. -      {
  2050. -    if (bcast && (names[i].unicast || names[i].source == REGISTER))
  2051. -      return;
  2052. -  
  2053. -    if (ISGROUP(i))
  2054. -      return;
  2055. +    if (!n) {
  2056. +      struct in_addr ip;
  2057. +      unsigned long a;
  2058. +
  2059. +      /* only do DNS lookups if the query is for type 0x20 or type 0x0 */
  2060. +      if (name_type != 0x20 && name_type != 0) return;
  2061.  
  2062. -    retip = names[i].ip;
  2063. +      /* look it up with DNS */      
  2064. +      a = interpret_addr(qname);
  2065. +
  2066. +      if (!a) {
  2067. +    /* no luck with DNS. We could possibly recurse here XXXX */
  2068. +    return;
  2069.        }
  2070. -    else
  2071. -      {
  2072. -    if ((name_type!=0 && name_type!=0x3 && name_type!=0x20) ||
  2073. -        (bcast && !dns_serve)) {
  2074. -      return;
  2075. -    } else {
  2076. -      unsigned long a;
  2077.  
  2078. -      a = interpret_addr(qname);
  2079. -      if (!a) return;
  2080. +      /* add it to our cache of names. give it 2 hours in the cache */
  2081. +      putip((char *)&ip,(char *)&a);
  2082. +      n = add_host_entry(qname,name_type,True,2*60*60,DNS,ip);
  2083.  
  2084. -      /* here is where we might recurse */      
  2085. -      putip((char *)&retip,(char *)&a);
  2086. -        
  2087. -      if (bcast && is_mynet(retip))
  2088. -        return;
  2089. +      /* failed to add it? yikes! */
  2090. +      if (!n) return;
  2091. +    }
  2092.  
  2093. -      i = find_name(qname,name_type,True);
  2094. -      if (i < 0) {
  2095. -        if ((i=add_name())>=0) {
  2096. -          StrnCpy(names[i].name,qname,15);
  2097. -          names[i].type = name_type;
  2098. -          names[i].unicast = is_mynet(retip);
  2099. -          names[i].ip = retip;
  2100. -          names[i].valid = True;
  2101. -          names[i].ttl = 120; /* give it two minutes */
  2102. -          names[i].start_time = p->timestamp;
  2103. -          names[i].source = DNS;        
  2104. -        }
  2105. -      }
  2106. -    }
  2107. -    DEBUG(2,(" sending positive reply (%s)\n",inet_ntoa(retip)));
  2108. -      }
  2109. -  } else {
  2110. -    retip = myip;
  2111. -  }
  2112. +    /* don't respond to bcast queries for group names */
  2113. +    if (bcast && !n->unique) return;
  2114. +
  2115. +    /* don't respond to bcast queries for addresses on the same net as the machine 
  2116. +       doing the querying unless its our IP (or something from LMHOSTS) */
  2117. +    if (bcast && 
  2118. +    n->source != SELF && n->source != LMHOSTS && 
  2119. +    same_net(n->ip,p->ip)) return;
  2120. +
  2121. +    /* is our entry already dead? */
  2122. +    if (n->death_time) {
  2123. +      if (n->death_time < p->timestamp) return;
  2124. +      ttl = n->death_time - p->timestamp;
  2125. +    }
  2126. +
  2127. +    retip = n->ip;
  2128. +    unique = n->unique;
  2129. +  } 
  2130. +
  2131. +  /* if the IP is 0 then substitute my IP - we should see which one is on the 
  2132. +     right interface for the caller to do this right */
  2133. +  if (zero_ip(retip)) retip = myip;
  2134.    
  2135.  
  2136. +  DEBUG(3,("Name query for name %s(%x) at %s rcode=%d\n",
  2137. +       nmb->question.question_name.name,
  2138. +       nmb->question.question_name.name_type,
  2139. +       inet_ntoa(retip),rcode));
  2140. +
  2141. +
  2142.    /* a lot of fields get copied from the query. This gives us the IP
  2143.       and port the reply will be sent to etc */
  2144.    p2 = *p;
  2145. @@ -1482,6 +883,7 @@
  2146.    nmb2->header.ancount = 1;
  2147.    nmb2->header.nscount = 0;
  2148.    nmb2->header.arcount = 0;
  2149. +  nmb2->header.rcode = rcode;
  2150.  
  2151.    nmb2->answers = &answer_rec;
  2152.    bzero((char *)nmb2->answers,sizeof(*nmb2->answers));
  2153. @@ -1489,9 +891,9 @@
  2154.    nmb2->answers->rr_name = nmb->question.question_name;
  2155.    nmb2->answers->rr_type = nmb->question.question_type;
  2156.    nmb2->answers->rr_class = nmb->question.question_class;
  2157. -  nmb2->answers->ttl = 0; /* XXX what ttl to answer with? */
  2158. +  nmb2->answers->ttl = ttl; /* XXX what ttl to answer with? */
  2159.    nmb2->answers->rdlength = 6;
  2160. -  nmb2->answers->rdata[0] = 0; /* XXXX nbflags - what should this be? */
  2161. +  nmb2->answers->rdata[0] = unique?0:0x80; 
  2162.    nmb2->answers->rdata[1] = 0; 
  2163.    putip(&nmb2->answers->rdata[2],(char *)&retip);
  2164.  
  2165. @@ -1598,7 +1000,7 @@
  2166.      break;
  2167.  
  2168.        case DGRAM_PACKET:
  2169. -    /* process_dgram(p); */
  2170. +    process_dgram(p);
  2171.      break;
  2172.        }
  2173.  
  2174. @@ -1614,15 +1016,13 @@
  2175.    ***************************************************************************/
  2176.  void process(void)
  2177.  {
  2178. +
  2179.    while (True)
  2180.      {
  2181.        fd_set fds;
  2182.        int selrtn;
  2183.        struct timeval timeout;
  2184.  
  2185. -      do_registration_hook();
  2186. -      do_browse_hook();
  2187. -
  2188.        FD_ZERO(&fds);
  2189.        FD_SET(ClientNMB,&fds);
  2190.        FD_SET(ClientDGRAM,&fds);
  2191. @@ -1642,6 +1042,10 @@
  2192.        }
  2193.  
  2194.        run_packet_queue();
  2195. +
  2196. +      do_browse_hook();
  2197. +
  2198. +      housekeeping();
  2199.      }
  2200.  }
  2201.  
  2202. @@ -1661,7 +1065,7 @@
  2203.      }   
  2204.  
  2205.    if (isdaemon)
  2206. -    ClientNMB = open_socket_in(SOCK_DGRAM, port,*lookup?3:0);
  2207. +    ClientNMB = open_socket_in(SOCK_DGRAM, port,0);
  2208.    else
  2209.      ClientNMB = 0;
  2210.  
  2211. @@ -1723,10 +1127,6 @@
  2212.      if (p) *p = 0;
  2213.    }
  2214.  
  2215. -  add_host_name(myname,0x20,&myip);
  2216. -  add_host_name(myname,0x0,&myip);
  2217. -  add_host_name(myname,0x3,&myip);
  2218. -
  2219.    return True;
  2220.  }
  2221.  
  2222. @@ -1740,21 +1140,14 @@
  2223.    printf("Usage: %s [-n name] [-B bcast address] [-D] [-p port] [-d debuglevel] [-l log basename]\n",pname);
  2224.    printf("Version %s\n",VERSION);
  2225.    printf("\t-D                    become a daemon\n");
  2226. -  printf("\t-P                    passive only. don't respond\n");
  2227. -  printf("\t-R                    only reply to queries, don't actively send claims\n");
  2228.    printf("\t-p port               listen on the specified port\n");
  2229.    printf("\t-d debuglevel         set the debuglevel\n");
  2230.    printf("\t-l log basename.      Basename for log/debug files\n");
  2231.    printf("\t-n netbiosname.       the netbios name to advertise for this host\n");
  2232.    printf("\t-B broadcast address  the address to use for broadcasts\n");
  2233.    printf("\t-N netmask           the netmask to use for subnet determination\n");
  2234. -  printf("\t-L name              lookup this netbios name then exit\n");
  2235. -  printf("\t-S                   serve queries via DNS if not on the same subnet\n");
  2236.    printf("\t-H hosts file        load a netbios hosts file\n");
  2237.    printf("\t-G group name        add a group name to be part of\n");
  2238. -  printf("\t-b                   toggles browsing support (defaults to on)\n");
  2239. -  printf("\t-M group name        searches for a master browser for the given group\n");
  2240. -  printf("\t-T interval          sets the browse announcement interval in seconds\n");
  2241.    printf("\t-C comment           sets the machine comment that appears in browse lists\n");
  2242.    printf("\n");
  2243.  }
  2244. @@ -1762,16 +1155,15 @@
  2245.  
  2246.  /****************************************************************************
  2247.    main program
  2248. -****************************************************************************/
  2249. +  **************************************************************************/
  2250.  int main(int argc,char *argv[])
  2251.  {
  2252.    int port = NMB_PORT;
  2253.    int opt;
  2254. -  unsigned int lookup_type = 0;
  2255.    extern FILE *dbf;
  2256.    extern char *optarg;
  2257.  
  2258. -  *lookup = *host_file = 0;
  2259. +  *host_file = 0;
  2260.  
  2261.    TimeInit();
  2262.  
  2263. @@ -1794,14 +1186,12 @@
  2264.  
  2265.    signal(SIGHUP,SIGNAL_CAST sig_hup);
  2266.  
  2267. +  bcast_ip = *interpret_addr2("0.0.0.0");
  2268. +  myip = *interpret_addr2("0.0.0.0");
  2269.  
  2270. -  while ((opt = getopt (argc, argv, "T:O:M:I:C:bAL:i:B:N:Rn:l:d:Dp:hPSH:G:")) != EOF)
  2271. +  while ((opt = getopt (argc, argv, "T:O:I:C:bAi:B:N:Rn:l:d:Dp:hSH:G:")) != EOF)
  2272.      switch (opt)
  2273.        {
  2274. -      case 'T':
  2275. -    browse_interval = atoi(optarg);
  2276. -    browse_interval = MAX(browse_interval,10);
  2277. -    break;
  2278.        case 'O':
  2279.      strcpy(user_socket_options,optarg);
  2280.      break;
  2281. @@ -1809,47 +1199,26 @@
  2282.      strcpy(comment,optarg);
  2283.      break;
  2284.        case 'G':
  2285. -    add_group_name(optarg);
  2286. +    add_domain_entry(optarg,bcast_ip);
  2287.      break;
  2288. -      case 'A':
  2289. -    dns_serve = True;
  2290. -    break;
  2291.        case 'H':
  2292.      strcpy(host_file,optarg);
  2293.      break;
  2294.        case 'I':
  2295. -    {
  2296. -      unsigned long a = interpret_addr(optarg);
  2297. -      putip((char *)&myip,(char *)&a);
  2298. -      got_myip = True;
  2299. -    }
  2300. +    myip = *interpret_addr2(optarg);
  2301. +    got_myip = True;
  2302.      break;
  2303.        case 'B':
  2304. -    {
  2305. -      unsigned long a = interpret_addr(optarg);
  2306. -      putip((char *)&bcast_ip,(char *)&a);
  2307. -      got_bcast = True;
  2308. -    }
  2309. +    bcast_ip = *interpret_addr2(optarg);
  2310. +    got_bcast = True;
  2311.      break;
  2312.        case 'N':
  2313. -    {
  2314. -      unsigned long a = interpret_addr(optarg);
  2315. -      putip((char *)&Netmask,(char *)&a);
  2316. -      got_nmask = True;
  2317. -    }
  2318. +    Netmask = *interpret_addr2(optarg);
  2319. +    got_nmask = True;
  2320.      break;
  2321.        case 'n':
  2322.      strcpy(myname,optarg);
  2323.      break;
  2324. -      case 'P':
  2325. -    {
  2326. -      extern BOOL passive;
  2327. -      passive = True;
  2328. -    }
  2329. -    break;
  2330. -      case 'S':
  2331. -    dns_serve = !dns_serve;
  2332. -    break;
  2333.        case 'l':
  2334.      sprintf(debugf,"%s.nmb",optarg);
  2335.      break;
  2336. @@ -1857,18 +1226,6 @@
  2337.      strcpy(scope,optarg);
  2338.      strupper(scope);
  2339.      break;
  2340. -      case 'L':
  2341. -    strcpy(lookup,optarg);
  2342. -    break;
  2343. -      case 'M':
  2344. -    if (*optarg == '-') {
  2345. -      strcpy(lookup,"\01\02__MSBROWSE__\02");
  2346. -      lookup_type = 1;
  2347. -    } else {
  2348. -      strcpy(lookup,optarg);
  2349. -      lookup_type = 0x1d;
  2350. -    }
  2351. -    break;
  2352.        case 'D':
  2353.      is_daemon = True;
  2354.      break;
  2355. @@ -1888,9 +1245,6 @@
  2356.        }
  2357.  
  2358.    
  2359. -  if (*lookup)
  2360. -    DEBUGLEVEL++;
  2361. -  
  2362.    if (DEBUGLEVEL > 10)
  2363.      {
  2364.        extern FILE *login,*logout;
  2365. @@ -1901,13 +1255,6 @@
  2366.        logout = fopen(fname,"w");
  2367.      }
  2368.    
  2369. -  if (*lookup)
  2370. -    {
  2371. -      if (dbf)
  2372. -    fclose(dbf);
  2373. -      dbf = stdout;
  2374. -    }
  2375. -
  2376.    DEBUG(1,("%s netbios nameserver version %s started\n",timestring(),VERSION));
  2377.    DEBUG(1,("Copyright Andrew Tridgell 1994\n"));
  2378.  
  2379. @@ -1919,34 +1266,12 @@
  2380.  
  2381.    init_structs();
  2382.  
  2383. -  if (*lookup) {
  2384. -    BOOL bcast = True;
  2385. -    int retries = 2;
  2386. -    char *p = strchr(lookup,'#');
  2387. -    struct in_addr ip;
  2388. -    if (p) {
  2389. -      *p = 0;
  2390. -      sscanf(p+1,"%x",&lookup_type);
  2391. -      bcast = False;
  2392. -      retries = 1;
  2393. -    }
  2394. -    if (!open_sockets(True,port)) return(1);
  2395. -    while (retries--)
  2396. -      if (name_query(lookup,lookup_type,bcast,True,bcast_ip,&ip)) {
  2397. -    printf("%s %s\n",inet_ntoa(ip),lookup);
  2398. -    name_status(lookup,lookup_type,ip,NULL);
  2399. -    return(0);
  2400. -      } 
  2401. -    printf("couldn't find name %s\n",lookup);
  2402. -    return(0);
  2403. -  }
  2404. -
  2405.    if (!*comment)
  2406.      strcpy(comment,"Samba %v");
  2407.    string_sub(comment,"%v",VERSION);
  2408.    string_sub(comment,"%h",myhostname);
  2409.  
  2410. -  check_names();
  2411. +  add_my_names();
  2412.  
  2413.    DEBUG(3,("Checked names\n"));
  2414.    
  2415. diff -u -r --new-file last-version/source/nmblib.c samba-1.9.14p4/source/nmblib.c
  2416. --- last-version/source/nmblib.c    Tue Nov  7 22:25:10 1995
  2417. +++ samba-1.9.14p4/source/nmblib.c    Fri Nov 10 20:54:24 1995
  2418. @@ -27,6 +27,9 @@
  2419.  
  2420.  int num_good_sends=0;
  2421.  int  num_good_receives=0;
  2422. +static uint16 name_trn_id = 0;
  2423. +BOOL CanRecurse = True;
  2424. +extern pstring scope;
  2425.  
  2426.  /*******************************************************************
  2427.    handle "compressed" name pointers
  2428. @@ -116,11 +119,15 @@
  2429.  /*******************************************************************
  2430.    put a compressed nmb name into a buffer. return the length of the
  2431.    compressed name
  2432. +
  2433. +  compressed names are really weird. The "compression" doubles the
  2434. +  size. The idea is that it also means that compressed names conform
  2435. +  to the doman name system. See RFC1002.
  2436.    ******************************************************************/
  2437.  static int put_nmb_name(char *buf,int offset,struct nmb_name *name)
  2438.  {
  2439.    int ret,m;
  2440. -  char buf1[16];
  2441. +  fstring buf1;
  2442.    char *p;
  2443.  
  2444.    sprintf(buf1,"%-15.15s%c",name->name,name->name_type);
  2445. @@ -217,31 +224,43 @@
  2446.  /*******************************************************************
  2447.    parse a dgram packet. Return False if the packet can't be parsed 
  2448.    or is invalid for some reason, True otherwise 
  2449. +
  2450. +  this is documented in section 4.4.1 of RFC1002
  2451.    ******************************************************************/
  2452.  static BOOL parse_dgram(char *inbuf,int length,struct dgram_packet *dgram)
  2453.  {
  2454.    int offset;
  2455. +  int flags;
  2456.  
  2457.    bzero((char *)dgram,sizeof(*dgram));
  2458.  
  2459.    if (length < 14) return(False);
  2460.  
  2461. -  dgram->header.res = RSVAL(inbuf,0);
  2462. -  dgram->header.id = RSVAL(inbuf,2);
  2463. -  putip((char *)&dgram->header.ip,inbuf+4);
  2464. -  dgram->header.port = RSVAL(inbuf,8);
  2465. -  dgram->header.length = RSVAL(inbuf,10);
  2466. -  dgram->header.res2 = RSVAL(inbuf,12);
  2467. +  dgram->header.msg_type = CVAL(inbuf,0);
  2468. +  flags = CVAL(inbuf,1);
  2469. +  dgram->header.flags.node_type = (enum node_type)((flags>>2)&3);
  2470. +  if (flags & 1) dgram->header.flags.more = True;
  2471. +  if (flags & 2) dgram->header.flags.first = True;
  2472. +  dgram->header.dgm_id = RSVAL(inbuf,2);
  2473. +  putip((char *)&dgram->header.source_ip,inbuf+4);
  2474. +  dgram->header.source_port = RSVAL(inbuf,8);
  2475. +  dgram->header.dgm_length = RSVAL(inbuf,10);
  2476. +  dgram->header.packet_offset = RSVAL(inbuf,12);
  2477.  
  2478.    offset = 14;
  2479. -  offset += parse_nmb_name(inbuf,offset,length,&dgram->header.source_name);
  2480. -  offset += parse_nmb_name(inbuf,offset,length,&dgram->header.dest_name);
  2481. +
  2482. +  if (dgram->header.msg_type == 0x10 ||
  2483. +      dgram->header.msg_type == 0x11 ||
  2484. +      dgram->header.msg_type == 0x12) {      
  2485. +    offset += parse_nmb_name(inbuf,offset,length,&dgram->source_name);
  2486. +    offset += parse_nmb_name(inbuf,offset,length,&dgram->dest_name);
  2487. +  }
  2488.  
  2489. -  if (offset >= length || (length-offset > sizeof(dgram->smb_data))) 
  2490. +  if (offset >= length || (length-offset > sizeof(dgram->data))) 
  2491.      return(False);
  2492.  
  2493. -  dgram->smbsize = length-offset;
  2494. -  memcpy(dgram->smb_data,inbuf+offset,dgram->smbsize);
  2495. +  dgram->datasize = length-offset;
  2496. +  memcpy(dgram->data,inbuf+offset,dgram->datasize);
  2497.  
  2498.    return(True);
  2499.  }
  2500. @@ -369,6 +388,9 @@
  2501.  
  2502.    num_good_receives++;
  2503.  
  2504. +  DEBUG(4,("%s received a packet of len %d from (%s) port %d\n",
  2505. +       timestring(),length,inet_ntoa(packet->ip),packet->port));
  2506. +
  2507.    return(packet);
  2508.  }
  2509.                       
  2510. @@ -387,8 +409,8 @@
  2511.    sock_out.sin_port = htons( port );
  2512.    sock_out.sin_family = AF_INET;
  2513.    
  2514. -  DEBUG(3,("sending a packet of len %d to (%s) on port 137 of type DGRAM\n",
  2515. -       len,inet_ntoa(*ip)));
  2516. +  DEBUG(4,("%s sending a packet of len %d to (%s) on port %d\n",
  2517. +       timestring(),len,inet_ntoa(*ip),port));
  2518.      
  2519.    ret = (sendto(fd,buf,len,0,(struct sockaddr *)&sock_out,
  2520.          sizeof(sock_out)) >= 0);
  2521. @@ -402,6 +424,59 @@
  2522.    return(ret);
  2523.  }
  2524.  
  2525. +/*******************************************************************
  2526. +  build a dgram packet ready for sending
  2527. +
  2528. +  XXXX This currently doesn't handle packets to big for one
  2529. +  datagram. It should split them and use the packet_offset, more and
  2530. +  first flags to handle the fragmentation. Yuck.
  2531. +  ******************************************************************/
  2532. +static int build_dgram(char *buf,struct packet_struct *p)
  2533. +{
  2534. +  struct dgram_packet *dgram = &p->packet.dgram;
  2535. +  unsigned char *ubuf = (unsigned char *)buf;
  2536. +  int offset=0;
  2537. +
  2538. +  /* put in the header */
  2539. +  ubuf[0] = dgram->header.msg_type;
  2540. +  ubuf[1] = (((int)dgram->header.flags.node_type)<<2);
  2541. +  if (dgram->header.flags.more) ubuf[1] |= 1;
  2542. +  if (dgram->header.flags.first) ubuf[1] |= 2;
  2543. +  RSSVAL(ubuf,2,dgram->header.dgm_id);
  2544. +  putip(ubuf+4,(char *)&dgram->header.source_ip);
  2545. +  RSSVAL(ubuf,8,dgram->header.source_port);
  2546. +  RSSVAL(ubuf,12,dgram->header.packet_offset);
  2547. +
  2548. +  offset = 14;
  2549. +
  2550. +  if (dgram->header.msg_type == 0x10 ||
  2551. +      dgram->header.msg_type == 0x11 ||
  2552. +      dgram->header.msg_type == 0x12) {      
  2553. +    offset += put_nmb_name(ubuf,offset,&dgram->source_name);
  2554. +    offset += put_nmb_name(ubuf,offset,&dgram->dest_name);
  2555. +  }
  2556. +
  2557. +  memcpy(ubuf+offset,dgram->data,dgram->datasize);
  2558. +  offset += dgram->datasize;
  2559. +
  2560. +  /* automatically set the dgm_length */
  2561. +  dgram->header.dgm_length = offset;
  2562. +  RSSVAL(ubuf,10,dgram->header.dgm_length); 
  2563. +
  2564. +  return(offset);
  2565. +}
  2566. +
  2567. +/*******************************************************************
  2568. +  build a nmb name
  2569. +  ******************************************************************/
  2570. +void make_nmb_name(struct nmb_name *n,char *name,int type,char *this_scope)
  2571. +{
  2572. +  strcpy(n->name,name);
  2573. +  strupper(n->name);
  2574. +  n->name_type = type;
  2575. +  strcpy(n->scope,this_scope);
  2576. +}
  2577. +
  2578.  
  2579.  /*******************************************************************
  2580.    build a nmb packet ready for sending
  2581. @@ -471,7 +546,7 @@
  2582.        break;
  2583.  
  2584.      case DGRAM_PACKET:
  2585. -      /* len = build_dgram(buf,p); */
  2586. +      len = build_dgram(buf,p);
  2587.        break;
  2588.      }
  2589.  
  2590. @@ -500,5 +575,310 @@
  2591.      return(read_packet(fd,type));
  2592.  
  2593.    return(NULL);
  2594. +}
  2595. +
  2596. +
  2597. +/****************************************************************************
  2598. +interpret a node status response
  2599. +****************************************************************************/
  2600. +static void interpret_node_status(char *p, char *master)
  2601. +{
  2602. +  int level = master?3:0;
  2603. +  int numnames = CVAL(p,0);
  2604. +  DEBUG(level,("received %d names\n",numnames));
  2605. +
  2606. +  p += 1;
  2607. +  while (numnames--)
  2608. +    {
  2609. +      char qname[17];
  2610. +      int type;
  2611. +      fstring flags="";
  2612. +      StrnCpy(qname,p,15);
  2613. +      type = CVAL(p,15);
  2614. +      p += 16;
  2615. +
  2616. +      if (p[0] & 0x80) strcat(flags,"<GROUP> ");
  2617. +      if (p[0] & 0x60 == 0) strcat(flags,"B ");
  2618. +      if (p[0] & 0x60 == 1) strcat(flags,"P ");
  2619. +      if (p[0] & 0x60 == 2) strcat(flags,"M ");
  2620. +      if (p[0] & 0x60 == 3) strcat(flags,"_ ");
  2621. +      if (p[0] & 0x10) strcat(flags,"<DEREGISTERING> ");
  2622. +      if (p[0] & 0x08) strcat(flags,"<CONFLICT> ");
  2623. +      if (p[0] & 0x04) strcat(flags,"<ACTIVE> ");
  2624. +      if (p[0] & 0x02) strcat(flags,"<PERMANENT> ");
  2625. +
  2626. +      if (master && type == 0x1d) {
  2627. +    StrnCpy(master,qname,15);
  2628. +    trim_string(master,NULL," ");
  2629. +      }
  2630. +      
  2631. +      DEBUG(level,("\t%s (type=0x%x)\t%s\n",qname,type,flags));
  2632. +      p+=2;
  2633. +    }
  2634. +  DEBUG(level,("num_good_sends=%d num_good_receives=%d\n",
  2635. +           IVAL(p,20),IVAL(p,24)));
  2636. +}
  2637. +
  2638. +
  2639. +/****************************************************************************
  2640. +  do a netbios name status to a host
  2641. +  **************************************************************************/
  2642. +BOOL name_status(int fd,char *name,int name_type,BOOL recurse,
  2643. +            struct in_addr to_ip,char *master,void (*fn)())
  2644. +{
  2645. +  BOOL found=False;
  2646. +  int retries = 2;
  2647. +  int retry_time = 5000;
  2648. +  struct timeval tval;
  2649. +  struct packet_struct p;
  2650. +  struct packet_struct *p2;
  2651. +  struct nmb_packet *nmb = &p.packet.nmb;
  2652. +
  2653. +  bzero((char *)&p,sizeof(p));
  2654. +
  2655. +  if (!name_trn_id) name_trn_id = (time(NULL)%0x7FFF) + (getpid()%100);
  2656. +  name_trn_id = (name_trn_id+1) % 0x7FFF;
  2657. +
  2658. +  nmb->header.name_trn_id = name_trn_id;
  2659. +  nmb->header.opcode = 0;
  2660. +  nmb->header.response = False;
  2661. +  nmb->header.nm_flags.bcast = False;
  2662. +  nmb->header.nm_flags.recursion_available = CanRecurse;
  2663. +  nmb->header.nm_flags.recursion_desired = recurse;
  2664. +  nmb->header.nm_flags.trunc = False;
  2665. +  nmb->header.nm_flags.authoritative = False;
  2666. +  nmb->header.rcode = 0;
  2667. +  nmb->header.qdcount = 1;
  2668. +  nmb->header.ancount = 0;
  2669. +  nmb->header.nscount = 0;
  2670. +  nmb->header.arcount = 0;
  2671. +
  2672. +  make_nmb_name(&nmb->question.question_name,name,name_type,scope);
  2673. +
  2674. +  nmb->question.question_type = 0x21;
  2675. +  nmb->question.question_class = 0x1;
  2676. +
  2677. +  p.ip = to_ip;
  2678. +  p.port = NMB_PORT;
  2679. +  p.fd = fd;
  2680. +  p.timestamp = time(NULL);
  2681. +  p.packet_type = NMB_PACKET;
  2682. +
  2683. +  GetTimeOfDay(&tval);
  2684. +
  2685. +  if (!send_packet(&p)) 
  2686. +    return(False);
  2687. +
  2688. +  retries--;
  2689. +
  2690. +  while (1)
  2691. +    {
  2692. +      struct timeval tval2;
  2693. +      GetTimeOfDay(&tval2);
  2694. +      if (TvalDiff(&tval,&tval2) > retry_time) {
  2695. +    if (!retries) break;
  2696. +    if (!found && !send_packet(&p))
  2697. +      return False;
  2698. +    GetTimeOfDay(&tval);
  2699. +    retries--;
  2700. +      }
  2701. +
  2702. +      if ((p2=receive_packet(fd,NMB_PACKET,90)))
  2703. +    {     
  2704. +      struct nmb_packet *nmb2 = &p2->packet.nmb;
  2705. +      if (nmb->header.name_trn_id != nmb2->header.name_trn_id ||
  2706. +          !nmb2->header.response) {
  2707. +        /* its not for us - maybe deal with it later */
  2708. +        if (fn) 
  2709. +          fn(p2);
  2710. +        else
  2711. +          free_packet(p2);
  2712. +        continue;
  2713. +      }
  2714. +      
  2715. +      if (nmb2->header.opcode != 0 ||
  2716. +          nmb2->header.nm_flags.bcast ||
  2717. +          nmb2->header.rcode ||
  2718. +          !nmb2->header.ancount) {
  2719. +        /* XXXX what do we do with this? could be a redirect, but
  2720. +           we'll discard it for the moment */
  2721. +        free_packet(p2);
  2722. +        continue;
  2723. +      }
  2724. +
  2725. +      interpret_node_status(&nmb2->answers->rdata[0], master);
  2726. +      free_packet(p2);
  2727. +      return(True);
  2728. +    }
  2729. +    }
  2730. +  
  2731. +
  2732. +  DEBUG(0,("No status response (this is not unusual)\n"));
  2733. +
  2734. +  return(False);
  2735. +}
  2736. +
  2737. +
  2738. +/****************************************************************************
  2739. +  do a netbios name query to find someones IP
  2740. +  ****************************************************************************/
  2741. +BOOL name_query(int fd,char *name,int name_type, 
  2742. +        BOOL bcast,BOOL recurse,
  2743. +        struct in_addr to_ip, struct in_addr *ip,void (*fn)())
  2744. +{
  2745. +  BOOL found=False;
  2746. +  int retries = 3;
  2747. +  int retry_time = bcast?250:5000;
  2748. +  struct timeval tval;
  2749. +  struct packet_struct p;
  2750. +  struct packet_struct *p2;
  2751. +  struct nmb_packet *nmb = &p.packet.nmb;
  2752. +
  2753. +  bzero((char *)&p,sizeof(p));
  2754. +
  2755. +  if (!name_trn_id) name_trn_id = (time(NULL)%0x7FFF) + (getpid()%100);
  2756. +  name_trn_id = (name_trn_id+1) % 0x7FFF;
  2757. +
  2758. +  nmb->header.name_trn_id = name_trn_id;
  2759. +  nmb->header.opcode = 0;
  2760. +  nmb->header.response = False;
  2761. +  nmb->header.nm_flags.bcast = bcast;
  2762. +  nmb->header.nm_flags.recursion_available = CanRecurse;
  2763. +  nmb->header.nm_flags.recursion_desired = recurse;
  2764. +  nmb->header.nm_flags.trunc = False;
  2765. +  nmb->header.nm_flags.authoritative = False;
  2766. +  nmb->header.rcode = 0;
  2767. +  nmb->header.qdcount = 1;
  2768. +  nmb->header.ancount = 0;
  2769. +  nmb->header.nscount = 0;
  2770. +  nmb->header.arcount = 0;
  2771. +
  2772. +  make_nmb_name(&nmb->question.question_name,name,name_type,scope);
  2773. +
  2774. +  nmb->question.question_type = 0x20;
  2775. +  nmb->question.question_class = 0x1;
  2776. +
  2777. +  p.ip = to_ip;
  2778. +  p.port = NMB_PORT;
  2779. +  p.fd = fd;
  2780. +  p.timestamp = time(NULL);
  2781. +  p.packet_type = NMB_PACKET;
  2782. +
  2783. +  GetTimeOfDay(&tval);
  2784. +
  2785. +  if (!send_packet(&p)) 
  2786. +    return(False);
  2787. +
  2788. +  retries--;
  2789. +
  2790. +  while (1)
  2791. +    {
  2792. +      struct timeval tval2;
  2793. +      GetTimeOfDay(&tval2);
  2794. +      if (TvalDiff(&tval,&tval2) > retry_time) {
  2795. +    if (!retries) break;
  2796. +    if (!found && !send_packet(&p))
  2797. +      return False;
  2798. +    GetTimeOfDay(&tval);
  2799. +    retries--;
  2800. +      }
  2801. +
  2802. +      if ((p2=receive_packet(fd,NMB_PACKET,90)))
  2803. +    {     
  2804. +      struct nmb_packet *nmb2 = &p2->packet.nmb;
  2805. +      if (nmb->header.name_trn_id != nmb2->header.name_trn_id ||
  2806. +          !nmb2->header.response) {
  2807. +        /* its not for us - maybe deal with it later (put it on the queue?) */
  2808. +        if (fn) 
  2809. +          fn(p2);
  2810. +        else
  2811. +          free_packet(p2);
  2812. +        continue;
  2813. +      }
  2814. +      
  2815. +      if (nmb2->header.opcode != 0 ||
  2816. +          nmb2->header.nm_flags.bcast ||
  2817. +          nmb2->header.rcode ||
  2818. +          !nmb2->header.ancount) {
  2819. +        /* XXXX what do we do with this? could be a redirect, but
  2820. +           we'll discard it for the moment */
  2821. +        free_packet(p2);
  2822. +        continue;
  2823. +      }
  2824. +
  2825. +      putip((char *)ip,&nmb2->answers->rdata[2]);
  2826. +      DEBUG(2,("Got a positive name query response from %s",
  2827. +           inet_ntoa(p2->ip)));
  2828. +      DEBUG(2,(" (%s)\n",inet_ntoa(*ip)));
  2829. +      found=True; retries=0;
  2830. +      free_packet(p2);
  2831. +    }
  2832. +    }
  2833. +
  2834. +  return(found);
  2835. +}
  2836. +
  2837. +
  2838. +/****************************************************************************
  2839. +  construct and send a netbios DGRAM
  2840. +  **************************************************************************/
  2841. +BOOL send_udp_dgram(int fd,char *buf,int len,
  2842. +               char *srcname,char *dstname,
  2843. +               int src_type,int dest_type,
  2844. +               struct in_addr dest_ip,
  2845. +               struct in_addr src_ip)
  2846. +{
  2847. +  struct packet_struct p;
  2848. +  struct dgram_packet *dgram = &p.packet.dgram;
  2849. +  char *ptr,*p2;
  2850. +  char tmp[4];
  2851. +
  2852. +  bzero((char *)&p,sizeof(p));
  2853. +
  2854. +  dgram->header.msg_type = 0x11; /* DIRECT GROUP DATAGRAM */
  2855. +  dgram->header.flags.node_type = M_NODE;
  2856. +  dgram->header.flags.first = True;
  2857. +  dgram->header.flags.more = False;
  2858. +  dgram->header.dgm_id = name_trn_id++;
  2859. +  dgram->header.source_ip = src_ip;
  2860. +  dgram->header.source_port = DGRAM_PORT;
  2861. +  dgram->header.dgm_length = 0; /* let build_dgram() handle this */
  2862. +  dgram->header.packet_offset = 0;
  2863. +  
  2864. +  make_nmb_name(&dgram->source_name,srcname,src_type,scope);
  2865. +  make_nmb_name(&dgram->dest_name,dstname,dest_type,scope);
  2866. +
  2867. +  ptr = &dgram->data[0];
  2868. +
  2869. +  /* now setup the smb part */
  2870. +  ptr -= 4; /* XXX ugliness because of handling of tcp SMB length */
  2871. +  memcpy(tmp,ptr,4);
  2872. +  set_message(ptr,17,17 + len,True);
  2873. +  memcpy(ptr,tmp,4);
  2874. +
  2875. +  CVAL(ptr,smb_com) = SMBtrans;
  2876. +  SSVAL(ptr,smb_vwv1,len);
  2877. +  SSVAL(ptr,smb_vwv11,len);
  2878. +  SSVAL(ptr,smb_vwv12,86);
  2879. +  SSVAL(ptr,smb_vwv13,3);
  2880. +  SSVAL(ptr,smb_vwv14,1);
  2881. +  SSVAL(ptr,smb_vwv15,1);
  2882. +  SSVAL(ptr,smb_vwv16,2);
  2883. +  p2 = smb_buf(ptr);
  2884. +  strcpy(p2,"\\MAILSLOT\\BROWSE");
  2885. +  p2 = skip_string(p2,1);
  2886. +
  2887. +  memcpy(p2,buf,len);
  2888. +  p2 += len;
  2889. +
  2890. +  dgram->datasize = PTR_DIFF(p2,ptr+4); /* +4 for tcp length */
  2891. +
  2892. +  p.ip = dest_ip;
  2893. +  p.port = DGRAM_PORT;
  2894. +  p.fd = fd;
  2895. +  p.timestamp = time(NULL);
  2896. +  p.packet_type = DGRAM_PACKET;
  2897. +
  2898. +  return(send_packet(&p));
  2899.  }
  2900.  
  2901. diff -u -r --new-file last-version/source/nmblookup.c samba-1.9.14p4/source/nmblookup.c
  2902. --- last-version/source/nmblookup.c    Thu Jan  1 10:00:00 1970
  2903. +++ samba-1.9.14p4/source/nmblookup.c    Thu Nov  9 16:27:35 1995
  2904. @@ -0,0 +1,213 @@
  2905. +/* 
  2906. +   Unix SMB/Netbios implementation.
  2907. +   Version 1.9.
  2908. +   NBT client - used to lookup netbios names
  2909. +   Copyright (C) Andrew Tridgell 1994-1995
  2910. +   
  2911. +   This program is free software; you can redistribute it and/or modify
  2912. +   it under the terms of the GNU General Public License as published by
  2913. +   the Free Software Foundation; either version 2 of the License, or
  2914. +   (at your option) any later version.
  2915. +   
  2916. +   This program is distributed in the hope that it will be useful,
  2917. +   but WITHOUT ANY WARRANTY; without even the implied warranty of
  2918. +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  2919. +   GNU General Public License for more details.
  2920. +   
  2921. +   You should have received a copy of the GNU General Public License
  2922. +   along with this program; if not, write to the Free Software
  2923. +   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  2924. +   
  2925. +*/
  2926. +
  2927. +#include "includes.h"
  2928. +#include "nameserv.h"
  2929. +
  2930. +extern int DEBUGLEVEL;
  2931. +
  2932. +extern pstring scope;
  2933. +
  2934. +extern struct in_addr bcast_ip;
  2935. +extern pstring myhostname;
  2936. +
  2937. +static BOOL got_bcast = False;
  2938. +
  2939. +int ServerFD=-1;
  2940. +
  2941. +/****************************************************************************
  2942. +  open the socket communication
  2943. +  **************************************************************************/
  2944. +static BOOL open_sockets(void)
  2945. +{
  2946. +  struct hostent *hp;
  2947. +  /* get host info */
  2948. +  if ((hp = Get_Hostbyname(myhostname)) == 0) 
  2949. +    {
  2950. +      DEBUG(0,( "Get_Hostbyname: Unknown host. %s\n",myhostname));
  2951. +      return False;
  2952. +    }   
  2953. +
  2954. +  ServerFD = open_socket_in(SOCK_DGRAM, 0,3);
  2955. +
  2956. +  if (ServerFD == -1)
  2957. +    return(False);
  2958. +
  2959. +  set_socket_options(ServerFD,"SO_BROADCAST");
  2960. +
  2961. +  DEBUG(3, ("Socket opened.\n"));
  2962. +  return True;
  2963. +};
  2964. +
  2965. +
  2966. +/****************************************************************************
  2967. +  initialise connect, service and file structs
  2968. +****************************************************************************/
  2969. +static BOOL init_structs(void )
  2970. +{
  2971. +  struct in_addr myip;
  2972. +
  2973. +  if (!get_myname(myhostname,&myip))
  2974. +    return(False);
  2975. +
  2976. +  /* Read the broadcast address from the interface */
  2977. +  {
  2978. +    struct in_addr ip0,ip2;
  2979. +
  2980. +    ip0 = myip;
  2981. +
  2982. +    if (!got_bcast) {
  2983. +      get_broadcast(&ip0,&bcast_ip,&ip2);
  2984. +
  2985. +      DEBUG(2,("Using broadcast %s\n",inet_ntoa(bcast_ip)));
  2986. +    }
  2987. +  }
  2988. +
  2989. +  return True;
  2990. +}
  2991. +
  2992. +/****************************************************************************
  2993. +usage on the program
  2994. +****************************************************************************/
  2995. +static void usage(void)
  2996. +{
  2997. +  printf("Usage: nmblookup [-M] [-B bcast address] [-d debuglevel] name\n");
  2998. +  printf("Version %s\n",VERSION);
  2999. +  printf("\t-d debuglevel         set the debuglevel\n");
  3000. +  printf("\t-B broadcast address  the address to use for broadcasts\n");
  3001. +  printf("\t-M                    searches for a master browser\n");
  3002. +  printf("\t-S                    lookup node status as well\n");
  3003. +  printf("\n");
  3004. +}
  3005. +
  3006. +
  3007. +/****************************************************************************
  3008. +  main program
  3009. +****************************************************************************/
  3010. +int main(int argc,char *argv[])
  3011. +{
  3012. +  int opt;
  3013. +  unsigned int lookup_type = 0x20;
  3014. +  pstring lookup;
  3015. +  extern FILE *dbf;
  3016. +  extern int optind;
  3017. +  extern char *optarg;
  3018. +  BOOL find_master=False;
  3019. +  BOOL find_status=False;
  3020. +  int i;
  3021. +  
  3022. +  DEBUGLEVEL = 1;
  3023. +  *lookup = 0;
  3024. +
  3025. +  TimeInit();
  3026. +  charset_initialise();
  3027. +
  3028. +  dbf = stdout;
  3029. +
  3030. +  while ((opt = getopt(argc, argv, "p:d:B:i:SMh")) != EOF)
  3031. +    switch (opt)
  3032. +      {
  3033. +      case 'B':
  3034. +    {
  3035. +      unsigned long a = interpret_addr(optarg);
  3036. +      putip((char *)&bcast_ip,(char *)&a);
  3037. +      got_bcast = True;
  3038. +    }
  3039. +    break;
  3040. +      case 'i':
  3041. +    strcpy(scope,optarg);
  3042. +    strupper(scope);
  3043. +    break;
  3044. +      case 'M':
  3045. +    find_master = True;
  3046. +    break;
  3047. +      case 'S':
  3048. +    find_status = True;
  3049. +    break;
  3050. +      case 'd':
  3051. +    DEBUGLEVEL = atoi(optarg);
  3052. +    break;
  3053. +      case 'h':
  3054. +    usage();
  3055. +    exit(0);
  3056. +    break;
  3057. +      default:
  3058. +    usage();
  3059. +    exit(1);
  3060. +      }
  3061. +
  3062. +  if (argc < 2) {
  3063. +    usage();
  3064. +    exit(1);
  3065. +  }
  3066. +
  3067. +  init_structs();
  3068. +  if (!open_sockets()) return(1);
  3069. +
  3070. +  DEBUG(1,("Sending queries to %s\n",inet_ntoa(bcast_ip)));
  3071. +
  3072. +
  3073. +  for (i=optind;i<argc;i++)
  3074. +    {
  3075. +      BOOL bcast = True;
  3076. +      int retries = 2;
  3077. +      char *p;
  3078. +      struct in_addr ip;
  3079. +
  3080. +      strcpy(lookup,argv[i]);
  3081. +
  3082. +      if (find_master) {
  3083. +    if (*lookup == '-') {
  3084. +      strcpy(lookup,"\01\02__MSBROWSE__\02");
  3085. +      lookup_type = 1;
  3086. +    } else {
  3087. +      lookup_type = 0x1d;
  3088. +    }
  3089. +      }
  3090. +
  3091. +      p = strchr(lookup,'#');
  3092. +
  3093. +      if (p) {
  3094. +    *p = 0;
  3095. +    sscanf(p+1,"%x",&lookup_type);
  3096. +    bcast = False;
  3097. +    retries = 1;
  3098. +      }
  3099. +
  3100. +      if (name_query(ServerFD,lookup,lookup_type,bcast,True,
  3101. +             bcast_ip,&ip,NULL)) 
  3102. +    {
  3103. +      printf("%s %s\n",inet_ntoa(ip),lookup);
  3104. +      if (find_status) 
  3105. +        {
  3106. +          printf("Looking up status of %s\n",inet_ntoa(ip));
  3107. +          name_status(ServerFD,lookup,lookup_type,True,ip,NULL,NULL);
  3108. +          printf("\n");
  3109. +        }
  3110. +      } else {
  3111. +    printf("couldn't find name %s\n",lookup);
  3112. +      }
  3113. +    }
  3114. +
  3115. +  return(0);
  3116. +}
  3117. diff -u -r --new-file last-version/source/password.c samba-1.9.14p4/source/password.c
  3118. --- last-version/source/password.c    Sun Nov  5 15:51:20 1995
  3119. +++ samba-1.9.14p4/source/password.c    Fri Nov 10 18:27:37 1995
  3120. @@ -1231,9 +1231,10 @@
  3121.    standard_sub_basic(desthost);
  3122.    strupper(desthost);
  3123.  
  3124. -  {
  3125. -    unsigned long a = interpret_addr(desthost);
  3126. -    putip((char *)&dest_ip,(char *)&a);
  3127. +  dest_ip = *interpret_addr2(desthost);
  3128. +  if (zero_ip(dest_ip)) {
  3129. +    DEBUG(1,("Can't find password server\n"));
  3130. +    return(False);
  3131.    }
  3132.  
  3133.    if (memcmp(&dest_ip,&myip,sizeof(dest_ip)) == 0) {
  3134. @@ -1241,7 +1242,7 @@
  3135.      return(False);
  3136.    }
  3137.  
  3138. -  password_client = open_socket_out(&dest_ip, port);
  3139. +  password_client = open_socket_out(SOCK_STREAM, &dest_ip, port);
  3140.    if (password_client < 0) {
  3141.      DEBUG(1,("%s not available\n",pserver));
  3142.      return(False);
  3143. diff -u -r --new-file last-version/source/printing.c samba-1.9.14p4/source/printing.c
  3144. --- last-version/source/printing.c    Mon Nov  6 16:53:58 1995
  3145. +++ samba-1.9.14p4/source/printing.c    Fri Nov 10 10:41:24 1995
  3146. @@ -25,8 +25,6 @@
  3147.  extern connection_struct Connections[];
  3148.  extern files_struct Files[];
  3149.  
  3150. -/*BOOL lpq_cache_reset = False;*/
  3151. -
  3152.  static BOOL * lpq_cache_reset=NULL;
  3153.  
  3154.  static int check_lpq_cache(int snum) {
  3155. diff -u -r --new-file last-version/source/server.c samba-1.9.14p4/source/server.c
  3156. --- last-version/source/server.c    Tue Nov  7 18:24:54 1995
  3157. +++ samba-1.9.14p4/source/server.c    Fri Nov 10 18:28:21 1995
  3158. @@ -3533,7 +3533,7 @@
  3159.          return(ERROR(ERRSRV,ERRaccess));        
  3160.  
  3161.        /* load service specific parameters */
  3162. -      if (OPEN_CNUM(cnum) && !become_service(cnum,(flags & AS_USER)))
  3163. +      if (OPEN_CNUM(cnum) && !become_service(cnum,(flags & AS_USER)?True:False))
  3164.          return(ERROR(ERRSRV,ERRaccess));
  3165.  
  3166.        /* does this protocol need to be run as guest? */
  3167. @@ -3739,9 +3739,8 @@
  3168.  #if PRIME_NMBD
  3169.    DEBUG(3,("priming nmbd\n"));
  3170.    {
  3171. -    struct in_addr ip;
  3172. -    uint32 a = interpret_addr("localhost");
  3173. -    putip((void *)&ip,(void *)&a);
  3174. +    struct in_addr ip = *interpret_addr2("localhost");
  3175. +    if (zero_ip(ip)) ip = *interpret_addr2("127.0.0.1");
  3176.      *OutBuffer = 0;
  3177.      send_one_packet(OutBuffer,1,&ip,137,SOCK_DGRAM);
  3178.    }
  3179. diff -u -r --new-file last-version/source/smb.h samba-1.9.14p4/source/smb.h
  3180. --- last-version/source/smb.h    Tue Nov  7 18:24:53 1995
  3181. +++ samba-1.9.14p4/source/smb.h    Fri Nov 10 18:56:23 1995
  3182. @@ -769,7 +769,7 @@
  3183.  BOOL mask_match( char *str, char *regexp, int case_sig, BOOL autoext);
  3184.  int dos_mode(int ,char *,struct stat *);
  3185.  char *timestring();
  3186. -BOOL ip_equal(struct in_addr *ip1,struct in_addr *ip2);
  3187. +BOOL ip_equal(struct in_addr ip1,struct in_addr ip2);
  3188.  BOOL send_one_packet(char *buf,int len,struct in_addr *ip,int port,int type);
  3189.  char *get_home_dir(char *);
  3190.  int set_filelen(int fd, long len);
  3191. @@ -808,7 +808,6 @@
  3192.  BOOL set_filetime(char *fname,time_t mtime);
  3193.  char *dirname_dos(char *path,char *buf);
  3194.  BOOL get_myname(char *myname,struct in_addr *ip);
  3195. -BOOL ip_equal(struct in_addr *ip1,struct in_addr *ip2);
  3196.  void expand_mask(char *Mask, BOOL);
  3197.  BOOL sane_unix_date(time_t unixdate);
  3198.  time_t start_of_month(void);
  3199. @@ -816,7 +815,9 @@
  3200.  char *smb_fn_name(int cnum);
  3201.  void get_machine_info(void);
  3202.  int open_socket_in(int type, int port, int dlevel);
  3203. -int open_socket_out(struct in_addr *addr, int port );
  3204. +int open_socket_out(int type,struct in_addr *addr, int port );
  3205. +struct in_addr *interpret_addr2(char *str);
  3206. +BOOL zero_ip(struct in_addr ip);
  3207.  int read_max_udp(int fd,char *buffer,int bufsize,int maxtime);
  3208.  void log_in(char *buffer,int len);
  3209.  int interpret_protocol(char *str,int def);
  3210. diff -u -r --new-file last-version/source/smbpasswd.c samba-1.9.14p4/source/smbpasswd.c
  3211. --- last-version/source/smbpasswd.c    Mon Nov  6 16:54:38 1995
  3212. +++ samba-1.9.14p4/source/smbpasswd.c    Fri Nov 10 10:41:23 1995
  3213. @@ -22,11 +22,6 @@
  3214.  #include "includes.h"
  3215.  #include "des.h"
  3216.  
  3217. -#ifdef SMBGETPASS
  3218. -extern char    *getsmbpass(char *);
  3219. -#define getpass getsmbpass
  3220. -#endif
  3221. -
  3222.  /* Static buffers we will return. */
  3223.  static struct smb_passwd pw_buf;
  3224.  static pstring  user_name;
  3225. diff -u -r --new-file last-version/source/util.c samba-1.9.14p4/source/util.c
  3226. --- last-version/source/util.c    Tue Nov  7 18:24:45 1995
  3227. +++ samba-1.9.14p4/source/util.c    Fri Nov 10 19:38:26 1995
  3228. @@ -1416,14 +1416,17 @@
  3229.  ********************************************************************/
  3230.  int ChDir(char *path)
  3231.  {
  3232. +  int res;
  3233.    static pstring LastDir="";
  3234.  
  3235.    if (strcsequal(path,".")) return(0);
  3236.  
  3237.    if (*path == '/' && strcsequal(LastDir,path)) return(0);
  3238.    DEBUG(3,("chdir to %s\n",path));
  3239. -  strcpy(LastDir,path);
  3240. -  return(sys_chdir(path));
  3241. +  res = sys_chdir(path);
  3242. +  if (!res)
  3243. +    strcpy(LastDir,path);
  3244. +  return(res);
  3245.  }
  3246.  
  3247.  
  3248. @@ -1947,8 +1950,6 @@
  3249.  
  3250.    lastip = *(struct in_addr *) &sock.sa_data[2];
  3251.    lastport = ntohs(((struct sockaddr_in *)&sock)->sin_port);
  3252. -  if (DEBUGLEVEL > 0)
  3253. -    DEBUG(3,("read %d bytes\n",ret));
  3254.  
  3255.    return(ret);
  3256.  }
  3257. @@ -3481,15 +3482,12 @@
  3258.  /****************************************************************************
  3259.  true if two IP addresses are equal
  3260.  ****************************************************************************/
  3261. -BOOL ip_equal(struct in_addr *ip1,struct in_addr *ip2)
  3262. +BOOL ip_equal(struct in_addr ip1,struct in_addr ip2)
  3263.  {
  3264. -  char *p1=(char *)ip1;
  3265. -  char *p2=(char *)ip2;
  3266. -  int l = sizeof(*ip1);
  3267. -  while (l--)
  3268. -    if (*p1++ != *p2++)
  3269. -      return(False);
  3270. -  return(True);
  3271. +  unsigned long a1,a2;
  3272. +  putip((char *)&a1,(char *)&ip1);
  3273. +  putip((char *)&a2,(char *)&ip2);
  3274. +  return(a1 == a2);
  3275.  }
  3276.  
  3277.  
  3278. @@ -3533,19 +3531,21 @@
  3279.    /* now we've got a socket - we need to bind it */
  3280.    if (bind(res, (struct sockaddr * ) &sock,sizeof(sock)) < 0) 
  3281.      { 
  3282. -      if (port == 139 || port == 137)
  3283. -    DEBUG(dlevel,("bind failed on port %d\n",port)); 
  3284. -      close(res); 
  3285. +      if (port) {
  3286. +    if (port == 139 || port == 137)
  3287. +      DEBUG(dlevel,("bind failed on port %d\n",port)); 
  3288. +    close(res); 
  3289.  
  3290. -      if (dlevel > 0 && port < 1000)
  3291. -    port = 7999;
  3292. +    if (dlevel > 0 && port < 1000)
  3293. +      port = 7999;
  3294.  
  3295. -      if (port >= 1000 && port < 9000)
  3296. -    return(open_socket_in(type,port+1,dlevel));
  3297. +    if (port >= 1000 && port < 9000)
  3298. +      return(open_socket_in(type,port+1,dlevel));
  3299. +      }
  3300.  
  3301.        return(-1); 
  3302.      }
  3303. -  DEBUG(1,("bind succeeded on port %d\n",port));
  3304. +  DEBUG(3,("bind succeeded on port %d\n",port));
  3305.  
  3306.    {
  3307.      int one=1;
  3308. @@ -3557,17 +3557,19 @@
  3309.  
  3310.  
  3311.  /****************************************************************************
  3312. -create an outgoing socket
  3313. -****************************************************************************/
  3314. -int open_socket_out(struct in_addr *addr, int port )
  3315. +  create an outgoing socket
  3316. +  **************************************************************************/
  3317. +int open_socket_out(int type, struct in_addr *addr, int port )
  3318.  {
  3319.    struct sockaddr_in sock_out;
  3320.    int res;
  3321.  
  3322.    /* create a socket to write to */
  3323. -  res = socket(PF_INET, SOCK_STREAM, 0);
  3324. +  res = socket(PF_INET, type, 0);
  3325.    if (res == -1) 
  3326.      { DEBUG(0,("socket error\n")); return -1; }
  3327. +
  3328. +  if (type != SOCK_STREAM) return(res);
  3329.    
  3330.    bzero((char *)&sock_out,sizeof(sock_out));
  3331.    putip((char *)&sock_out.sin_addr,(char *)addr);
  3332. @@ -3578,8 +3580,11 @@
  3333.    DEBUG(3,("Connecting to %s at port %d\n",inet_ntoa(*addr),port));
  3334.    
  3335.    /* and connect it to the destination */
  3336. -  if (connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out))<0)
  3337. -    { DEBUG(0,("connect error: %s\n",strerror(errno))); close(res); return -1; }
  3338. +  if (connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out))<0) {
  3339. +    DEBUG(0,("connect error: %s\n",strerror(errno))); 
  3340. +    close(res); 
  3341. +    return(-1);
  3342. +  }
  3343.  
  3344.    return res;
  3345.  }
  3346. @@ -3634,21 +3639,47 @@
  3347.    struct hostent *hp;
  3348.    unsigned long res;
  3349.  
  3350. -  /* if it's in the form of an IP address then get the lib to interpret it */
  3351. -  if (isdigit(str[0]))
  3352. -    return(inet_addr(str));
  3353. +  if (strcmp(str,"0.0.0.0") == 0) return(0);
  3354. +  if (strcmp(str,"255.255.255.255") == 0) return(0xFFFFFFFF);
  3355.  
  3356. -  /* otherwise assume it's a network name of some sort and use Get_Hostbyname */
  3357. -  if ((hp = Get_Hostbyname(str)) == 0) 
  3358. -    {
  3359. +  /* if it's in the form of an IP address then get the lib to interpret it */
  3360. +  if (isdigit(str[0])) {
  3361. +    res = inet_addr(str);
  3362. +  } else {
  3363. +    /* otherwise assume it's a network name of some sort and use Get_Hostbyname */
  3364. +    if ((hp = Get_Hostbyname(str)) == 0) {
  3365.        DEBUG(0,("Get_Hostbyname: Unknown host. %s\n",str));
  3366.        return 0;
  3367.      }
  3368. +    putip((char *)&res,(char *)hp->h_addr);
  3369. +  }
  3370. +
  3371. +  if (res == (unsigned long)-1) return(0);
  3372.  
  3373. -  putip((char *)&res,(char *)hp->h_addr);
  3374.    return(res);
  3375.  }
  3376.  
  3377. +/*******************************************************************
  3378. +  a convenient addition to interpret_addr()
  3379. +  ******************************************************************/
  3380. +struct in_addr *interpret_addr2(char *str)
  3381. +{
  3382. +  static struct in_addr ret;
  3383. +  unsigned long a = interpret_addr(str);
  3384. +  putip((char *)&ret,(char *)&a);
  3385. +  return(&ret);
  3386. +}
  3387. +
  3388. +/*******************************************************************
  3389. +  check if an IP is the 0.0.0.0
  3390. +  ******************************************************************/
  3391. +BOOL zero_ip(struct in_addr ip)
  3392. +{
  3393. +  unsigned long a;
  3394. +  putip((char *)&a,(char *)&ip);
  3395. +  return(a == 0);
  3396. +}
  3397. +
  3398.  #define TIME_FIXUP_CONSTANT (369.0*365.25*24*60*60-(3.0*24*60*60+6.0*60*60))
  3399.  
  3400.  /****************************************************************************
  3401. @@ -4188,11 +4219,10 @@
  3402.  
  3403.  #ifdef REPLACE_RENAME
  3404.  /* Rename a file. (from libiberty in GNU binutils)  */
  3405. -
  3406.  int
  3407.  rename (zfrom, zto)
  3408. -     char *zfrom;
  3409. -     char *zto;
  3410. +     const char *zfrom;
  3411. +     const char *zto;
  3412.  {
  3413.    if (link (zfrom, zto) < 0)
  3414.      {
  3415. @@ -4204,7 +4234,6 @@
  3416.      }
  3417.    return unlink (zfrom);
  3418.  }
  3419. -
  3420.  #endif
  3421.  
  3422.  #if WRAP_MEMCPY
  3423. diff -u -r --new-file last-version/source/version.h samba-1.9.14p4/source/version.h
  3424. --- last-version/source/version.h    Tue Nov  7 23:00:33 1995
  3425. +++ samba-1.9.14p4/source/version.h    Fri Nov 10 23:32:13 1995
  3426. @@ -1 +1 @@
  3427. -#define VERSION "1.9.14p3"
  3428. +#define VERSION "1.9.14p4"
  3429.